2011-11-01 148 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(); 

}