2014-05-07 207 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分鐘)。如果線程檢測到它已經接近極限,它應該優雅地停止它的處理,並且可能會通知應用程序或系統的其餘部分它沒有完成。