从另一个线程操纵线程执行的可能方法?

时间:2010-09-30 13:42:58

标签: c# multithreading .net-3.5 thread-safety

这是两部分问题。

首先,假设我有一个在另一个线程中执行的函数:

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)强制a(),b()和c()抛出MyException。然后我可以在catch块中等待,直到“resume”按钮单击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首先引发异常的好方法。目前,我基本上检测了由(),b()和c()调用的低级代码,以查找要发出信号的事件,告诉他们抛出MyException。这是我所知道的唯一方法,你可以在一个线程上诱导另一个线程的行为。

真正想知道的是(并且我很确定这是不可能的),在.NET中有一些疯狂的方法让工作线程注册一个事件处理程序,所以当我从GUI中激活事件时,工作线程会立即停止正在执行的操作并执行处理程序?我想我基本上都在寻找类似中断服务程序的东西,就像你通常在微控制器上实现的那样。

2 个答案:

答案 0 :(得分:0)

我不知道.Net中存在优先级中断的微控制器式方法。但与此同时,您可能需要考虑一个共享标志,您的线程会不断检查它是否应该暂停或运行。一旦检测到暂停请求,它就可以等待Thread.SleepTimer检查是否允许运行。也许不像你希望的那样优雅,但它是可预测的并且易于实现。

答案 1 :(得分:0)

在针对这个问题采取一些不同的方法后,我认为我的东西运作良好。我基本上选择#2,因为它利用了AutoResetEvent的基本行为来暂停和恢复。

我的线程运行从Stateless派生的状态机,因此我能够将所有暂停和恢复功能放在基类中,这使我的代码变得干净整洁。我也可以通过覆盖派生类中的方法来获得特定于客户端的功能。

最后,在暂停的粒度和代码的优雅之间存在权衡。我牺牲了粒度,所以我没有在任何地方胡椒WaitOne()