2011-11-01 72 views
3

我有一個List(Of IWorker)其中包含一些混凝土。 IWorker依次具有Startup()Shutdown()方法。協調工作者線程關閉

在Worker類中,Startup()創建一個新的工作線程,然後返回。 Shutdown()目前設置私人ShutDownRequested標誌並返回。該標誌由工作者線程檢查(最壞每隔幾秒)。

這一切工作正常,但目前父應用程序無法確定工人是否已完成關閉。

我可以看到很多方法,但我不知道最好的是什麼。

  • State財產添加到IWorker。應該工作,但我會投票狀態,這似乎有點討厭。
  • 使關閉命令阻止 - 可能是我的理想解決方案,但我不知道如何實現它 - 工作人員Sunclock私人對象Shutdown()也應嘗試在設置標誌後的Synclock?
  • 還有別的嗎?

任何文章,意見或建議表示讚賞。 C#或VB中的例子很好。

+0

這取決於你想要做什麼以及爲什麼。調用'Shutdown()'時你想阻塞嗎?你想顯示給用戶的狀態?還有別的嗎? – svick

+0

@svick這是在控制檯應用程序中運行。目前,在調用啓動worker之後,控制檯每隔幾秒鐘循環一次,從worker讀取一些狀態信息並顯示它(處理的事件,使用的帶寬等)。當用戶按Enter鍵退出應用程序時,關機被髮送給每個工作人員。我只是想等到關機完成後,打印一個乾淨關機的確認信息,然後退出。如果應用程序沒有關閉並且工作人員退出,它將被回收並重新開始。 – Basic

回答

5

如果您希望關閉成爲阻止操作,我不會嘗試使用鎖定來阻止Shutdown()

如果你可以使用.NET 4,我會讓你的內部執行方法成爲一個任務。然後,您可以撥打Task.Wait()以阻止它完成。

如果您必須使用.NET 3.5或更早版本,我將在內部調用Shutdown()調用,等待WaitHandle,如ManualResetEvent。然後關閉代碼可能看起來像:

' Include: 
Private shutdownEvent as ManualResetEvent = new ManualResetEvent(false) 

Sub Shutdown() 
    ShutDownRequested = True 
    shutdownEvent.WaitOne() 
End Sub 

輪詢循環(線程操作)會那麼做:

Sub Execute() 
    While Not ShutDownRequested 
     ' Do your work 
    End While 

    ' Before you exit, "set" the event: 
    shutdownEvent.Set() 
End Sub 
+0

使用任務,您也可以使用'Task.WaitAll()'一次輕鬆地等待所有人。 – svick

+0

感謝您的詳細解答。我目前在這個項目中停留在3.5。你能解釋一下''ManualResetEvent'已經在使用'Thread.Join'的另一個答案中建議了什麼好處嗎? – Basic

+0

@Basiclife主要優點是:1)你可以*(可選)在WaitOne()上設置一個超時時間,這將允許你返回並且不會在寫入錯誤的'IWorker'時永遠阻塞,2)你不會不必保持對線程的引用,這可以在完成時進行GC調用。 3)對於發生的事情非常明確。 –

4

有一種方法Thread.Join將阻塞,直到線程結束 - 任何使用?

0

爲什麼不上IWorker添加ShutdownComplete事件,並確保它的最後一件事每個具體什麼時候完成?我知道這聽起來像是可能迫使實現去做某些特定的事情,但如果你有一個IWorker的基類,它應該是一個大問題。考慮這一點。

public abstract class WorkerBase : IWorker 
{ 
    public event EventHandler ShutdownComplete; 
    //...other implemenation details 

    public void Shutdown() 
    { 
    this.ShutdownInternal(); 
    this.ShutdownComplete(this, EventArgs.Empty); 
    } 

    protected abstract void ShutdownInternal(); 

}