2014-09-22 55 views
1

我有一個「工人」的過程,是一個專用的服務器上持續運行,發送電子郵件,處理數據提取等如何處理/執行單個實例線程

我想擁有所有這些過程的異步運行,但我只希望每個進程的一個實例在同一時間運行。如果一個進程已經運行,我不想排隊再運行它。

[例如,簡化]

while (true) 
{ 
    // SLEEP HERE 

     Task task1 = Task.Factory.StartNew(() => DataScheduleWorker.Run()); 

     Task task2 = Task.Factory.StartNew(() => EmailQueueWorker.Run()); 
} 

基本上,我想這整個過程無休止地運行,其中每個的運行彼此平行的任務,但在任何點僅運行一個每個任務的實例時間。

如何在C#5中實現此目的?實施這個最簡潔/最好的方法是什麼?

編輯

會的東西,因爲這足以作爲簡單的,或者這會不會壞掉?:

 Task dataScheduleTask = null; 

     while (true) 
     { 
      Thread.Sleep(600); 

      // Data schedule worker 

      if (dataScheduleTask != null && dataScheduleTask.IsCompleted) dataScheduleTask = null; 
      if (dataScheduleTask == null) 
      { 
       dataScheduleTask = Task.Factory.StartNew(() => DataScheduleWorker.Run()); 
      } 
     } 
+0

我不太清楚爲什麼你在循環中創建線程而不是重用工作。你可以看看SemaphoreSlim.wait()來阻止它們。 – 2014-09-22 16:50:22

+0

對不起 - 我的意思是在我的僞代碼中使用任務。更新。 SemaphoreSlim.Wait()會排隊嗎? – 2014-09-22 16:54:32

+0

這就是軟件工程中的「互斥」。你爲此使用互斥體。使它變得複雜的一點。 – 2014-09-22 17:02:24

回答

4

這聽起來像一個任意框架actors,或者可能TPL Dataflow一個完美的工作。從根本上說,每個工作都有一個演員(或塊),等待消息並獨立於其他演員處理它們。無論哪種情況,你的目標應該是儘可能少地寫入線程處理和消息傳遞代碼 - 最好不要。這個問題已經基本解決了;你只需要評估可用選項並使用最適合你的任務。我個人可能會從Dataflow開始。

+0

感謝Jon。我將閱讀Dataflow文檔... – 2014-09-22 17:17:32