2010-09-30 83 views
1

这是一个两部分的问题。从另一个线程处理线程执行的可能方法?

首先,让我们说,我有一个是在另一个线程执行的函数:

private AutoResetEvent StopEvent = new AutoResetEvent(false); 

public void WorkerThread() 
{ 
    while(!StopEvent.WaitOne(10)) { 
    a(); 
    b(); 
    c(); 
    } 
} 

现在我想暂停这个线程。 Thread.Suspend是不可能的,因为在调用它之后,它不能保证我没有死锁系统。等待另一个AutoResetEvent也是不希望的,因为暂停“粒度”会太大。我想出了两个“解决方案”,但我不激动不已要么他们(但#2此刻正优先)的:

1)交错PauseEvent.WaitOne()无处不在:

private AutoResetEvent StopEvent = new AutoResetEvent(false); 
private ManualResetEvent PauseEvent = new ManualResetEvent(true); 

public void WorkerThread() 
{ 
    while(!StopEvent.WaitOne(10)) { 
    PauseEvent.WaitOne(0); 
    a(); 
    PauseEvent.WaitOne(0); 
    b(); 
    PauseEvent.WaitOne(0); 
    c(); 
    } 
} 

2)强制(),b()和c()来抛出MyException。然后,我可以在catch块等到“恢复”按钮,点击信号PauseEvent:

private AutoResetEvent StopEvent = new AutoResetEvent(false); 
private AutoResetEvent PauseEvent = new AutoResetEvent(false); 

public void WorkerThread() 
{ 
    while(!StopEvent.WaitOne(10)) { 
    try { 
     a(); 
     b(); 
     c(); 
    } catch(MyException) { 
     PauseEvent.WaitOne(); // wait indefinitely until signaled by another thread 
    } 
    } 
} 

(2)真的好像要做到这一点的唯一方法,但我想知道是否有人已经尝试另一个“暂停”的方法。

其次,我得到绊倒的部分是解决方案#2诱导异常的好方法。目前,我已经基本上安装了由a(),b()和c()调用的低级代码来查找要发送信号的事件,以告诉它们抛出MyException。这是我知道的唯一方法,你可以在另一个线程上诱发行为。

我倒是真的想知道的是(我敢肯定这是不可能的),有没有在.NET中一些疯狂的方式,使一个工人线程注册事件处理程序,所以,当我火来自我的GUI的事件,工作线程立即停止它正在执行的操作并执行处理程序?我想我基本上是在寻找像中断服务程序那样的东西,就像你通常在微控制器上实现的那样。

回答

0

在解决了这个问题的几种不同方法之后,我认为我有一些工作得很好。我基本上与#2一起,因为它利用AutoResetEvent的基本行为来暂停和恢复。

我的线程运行从无状态派生的状态机,所以我能够将所有暂停和恢复功能放在基类中,这使得我的代码更加干净。我还可以通过重写派生类中的方法来获得客户端特定的功能。最后,在代码的粒度和代码的优雅之间进行了权衡。我牺牲了粒度,所以我不必在任何地方胡椒WaitOne()

0

我不知道在.Net中具有优先级中断的微控制器风格的方法。但在此期间,您可能需要考虑一个共享标志,您的线程会不断检查它是否应暂停或运行。一旦检测到暂停请求,它就可以使用Thread.SleepTimer来检查是否允许运行。也许不像你所期望的那样优雅,但它是可预测和易于实现的。

+0

标志方法基本上是我上面的第一个实现。可以肯定的是,这可能是唯一的方法。我今天正在开发实施#2,但是它在系统中有自己的奇特行为。 – Dave 2010-10-01 06:10:08