2014-05-07 157 views
0

我有一种方法,基本上从远程系统复制文件到我们的本地系统。这种方法需要在一小时内执行4次,每15分钟执行一次。该方法使用Period作为参数调用,其中Period的范围是0-3(0 = Min:0-15; 3 = Min:45-0)。在这种情况下使用线程?

我如何运行这些作为独立的线程,然后接下来的一个小时之前停止所有的人:20来,这样我可以调用外部程序ProcessFiles.EXE?我总是可以继续线程化,但是我不知道读取文件的程序是如何线程安全的。所以我更喜欢在下一个之前削减所有线程:20来临。

之前,15分钟的窗口是不是足够复制所有掉进这个15分钟的窗口中的文件的更多。不幸的是,这个过程变得非常缓慢。所以,假设我正在运行第一个IF语句(at:20),而不是在达到35分钟时停止它,我可以让它在一个线程中运行,直到小时结束。但是如果在下一个:20之后没有完成,那么该线程需要被停止。

编辑:这曾经是在任务计划程序。该任务会将20个文件复制15分钟的时间。不幸的是,文件复制变得非常缓慢。所以,现在,在某些块中,文件副本需要超过15分钟。

所以我最初的想法是线程这些过程。在第一个15分钟块(IF语句运行于分钟20,将文件从Min.00复制到Min.1)的情况下,假设我使用了一个线程。这意味着,即使没有完成分35(其中复制15.分钟,30.分钟的过程开始),它仍然有直到分钟下一次迭代的20(第一IF的声明循环)。

调度程序的缺点是,如果任务未按时完成,它将1)阻止调度程序再次运行任务,或2)如果强制它关闭,只复制部分内容被复制。

下面是我的一些代码,所以你有什么我工作的一个想法:

public static void Main(string[] args) 
{ 
    DateTime DateNow = new DateTime(2014, 3, 1, 5, 0, 0); //For the example, start at 5AM. 
    Thread thread0 ; 
    Thread thread1 ; 
    Thread thread2 ; 
    Thread thread3 ; 
    for (; ;) //infinite loop 
    { 
     //DateNow will usually be DateTime.Now. 
     if (DateNow.Minute == 20) 
     { 
      //Copy files from 5:00-5:15. 
      //IF any of the threads from Hour 4 are still running, they must be stopped 
      _CurrentHour = DateNow.Hour; 
      thread0 = new Thread(() => CopyFiles(_CurrentHour, 0)); 
      thread0.Start(); 
     } 
     else if (DateNow.Minute == 35) 
     { 
      //Copy files from 5:15-5:30. 
      thread1 = new Thread(() => CopyFiles(_CurrentHour, 1)); 
      thread1.Start(); 
     } 
     else if (DateNow.Minute == 50) 
     { 
      //Copy files from 5:30-5:45. 
      thread2 = new Thread(() => CopyFiles(_CurrentHour, 2)); 
      thread2.Start(); 
     } 
     else if (DateNow.Minute == 5) 
     { 
      //Copy files from 5:45-6:00. 
      thread3 = new Thread(() => CopyFiles(_CurrentHour, 3)); 
      thread3.Start(); 
     } 
     thread0.Join(); 
     thread1.Join(); 
     thread2.Join(); 
     thread3.Join(); 
     //CALL ProcessFiles.EXE 

    }  
} 
+0

其他程序是“别的东西”吗?跨进程线程同步非常不平凡。 – BradleyDotNET

+0

“别的东西”是另一个程序。 – vmgmail

+0

这不会抛出null参考?你的无限循环只能根据分钟创建thread0,1,2,3 ... –

回答

-2

在第一线,等待15分钟,然后复制文件:

System.Threading.Thread.Sleep(1000 * 60 * 15); // 15 mins 

如果你想杀死线程,你可以调用中止功能:

thread1.Abort(); 
+4

thread.Abort()是一个非常糟糕的主意。线程终止应该是合作的。 –

+1

'Sleep()'也不是完全可靠的 - 尽管线程正在请求,它可能不会完全是15分钟。 – Bobson

2

好像你正在寻找两件事情。

  1. 定期计时器。这些在.NET中在multiple flavors。您可以安排您的计时器每15分钟执行一次,并根据哪个季度或每小时执行一次,您可以决定要复制哪些文件。

  2. 排队工作单位在工作线程执行。同样,在这里您有多种选择,从使用托管线程池(直接通过ThreadPool API)或通过Task API(更简单),或者自行滚动(类似于您尝试执行的操作,这更复杂但更适合长时间运行任务)

为了解决您的其他问题,关于在15分钟窗口内停止工作线程,最好的选择是使其成为工作线程的责任。当计时器被触发时,您应该记录文件操作的开始时间,并且在工作线程中定期检查所用时间是否小于您所需的长度(15分钟)。如果线程检测到它已经接近极限,它应该优雅地停止它的处理,并且可能会通知应用程序或系统的其余部分它没有完成。