结合线程.带有new Thread()的计时器
本文关键字:计时器 Thread 线程 带有 new 结合 | 更新日期: 2023-09-27 18:03:25
我有一个控制台应用程序,它在每小时的00:00运行。这个控制台应用程序在同一小时的:15和:30复制文件。
这是我的初始代码,其中我使用WHILE
循环来检查当前分钟。我想用System.Threading.Timer
代替WHILE
环。
使用线程。计时器和不使用循环,我怎么能在启动控制台应用程序后15分钟启动Thread0,在30分钟启动Thread1 ?我不想使用第三方的、开源的解决方案。
CancellationTokenSource cts0 = new CancellationTokenSource();
CancellationTokenSource cts1 = new CancellationTokenSource();
Thread Thread0, Thread1;
DateTime TaskRunDateTime = DateTime.Now;
DateTime RightNow = DateTime.Now;
while (!thread0Running || !thread1Running)
{
if (RightNow.Minute == 15)
{
thread0Running = true;
Class myClass0 = new Class();
Thread0 = new Thread(() => myClass0.CopyFiles(15, cts0.Token));
Thread0.Start();
}
else if (RightNow.Minute == 30)
{
thread1Running = true;
Class myClass1 = new Class();
Thread1 = new Thread(() => myClass1.CopyFiles(30, cts1.Token));
Thread1.Start();
}
RightNow = DateTime.Now;
}
for (; ; )
{
fileCount = Directory.GetFiles(destPath, FileDate + "*.xml").Length;
If (fileCount == 20)
{
// All 20 files have been copied because the two threads have finished
RunExternalReportGeneratorEXE();
break;
}
else if (RightNow >= TaskRunDateTime.AddHours(2))
{
// Task took over 2 hours to complete.
// Cancel Thread0, Thread1 and run 3rd-party executable.
cts0.Cancel();
cts1.Cancel();
RunExternalReportGeneratorEXE();
break;
}
在应用程序启动时,您可以计算X:15和X:30将在多长时间内下降。然后,您可以使用Timer的构造函数来调度Timer回调的开始时间和频率。
创建两个可以等待的ManualResetEvent
对象。然后创建两个计时器:
ManualResetEvent Copy1Done = new ManualResetEvent(false);
ManualResetEvent Copy2Done = new ManualResetEvent(false);
Timer t1 = new Timer((s) =>
{
Class myClass0 = new Class();
myClass0.CopyFiles(15, cts0.Token);
Copy1Done.Set();
}, null, TimeSpan.FromMinutes(15), TimeSpan.FromMilliseconds(-1));
Timer t1 = new Timer((s) =>
{
Class myClass1 = new Class();
myClass0.CopyFiles(30, cts1.Token);
Copy2Done.Set();
}, null, TimeSpan.FromMinutes(30), TimeSpan.FromMilliseconds(-1));
这些是一次性计时器;他们会开一次枪,然后不会再开了。
现在,你要等两个小时来完成复印。这就是ManualResetEvent
对象的用武之地。创建一个事件数组:
WaitHandle[] handles = new WaitHandle[] {Copy1Done, Copy2Done};
// wait for both events to be signaled, or for two hours
if (!WaitHandle.WaitAll(handles, TimeSpan.FromHours(2)))
{
// took too long. Cancel the copies.
cts0.Cancel();
cts1.Cancel();
// you might want to wait here for the threads to exit.
// otherwise you might have a problem with a locked file.
}
// and run the program
RunExternalReportGeneratorEXE();
我不想在这里为你写完整的代码,但给你一个概念,你可以用线程定时器做什么:
void CreateTimer()
{
// Create an event to signal the timeout count threshold in the
// timer callback.
AutoResetEvent autoEvent = new AutoResetEvent(false);
// Create an inferred delegate that invokes methods for the timer.
TimerCallback tcb = CheckStatus;
// Create a timer that signals the delegate to invoke
// CheckStatus after 15 minutes.
// thereafter.
Console.WriteLine("{0} Creating timer.'n", DateTime.Now.ToString("h:mm:ss.fff"));
System.Threading.Timer Timer stateTimer = new Timer(tcb, autoEvent, 1000 * 60 *15, 0);
//Wait for 15 minutes
autoEvent.WaitOne(1000 * 60 *15, false);
stateTimer = new Timer(tcb, null, 1000 * 60 *30, 0);
}
// This method is called by the timer delegate.
public void CheckStatus(Object stateInfo)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), stateInfo);
}
public void DoWork(Object stateInfo)
{
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
autoEvent.Set();
//Change your worktype here.
CancellationTokenSource cts0 = new CancellationTokenSource();
Class myClass1 = new Class();
myClass1.CopyFiles(30, cts0.Token);
}