结合线程.带有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;
    }

结合线程.带有new Thread()的计时器

在应用程序启动时,您可以计算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);
}