工作线程和Dispose()

时间:2010-01-19 09:57:33

标签: c# clr dispose

我有一些带有工作线程的实用程序类,具有简单的退出条件。我在我的应用程序中使用此类。工作线程在类构造函数中创建并启动。

class MyClass
{
  Thread _thread;

// unrelevant details are omitted
void WorkerThreadRoutine
{
  while(_running)
 {
   // do some useful background work here
 }
}
}

我的问题是我什么时候必须设置_running = false。在C ++中具有确定性 资源释放生活很简单 - 我使用对象析构函数而不关心。

我会写类似

的内容
~MyClass()
{
  _running = false;
}

在C#中,没有C ++意义上的析构函数。我必须在这里写一些Dispose()函数 并使用IDisposable?我当然可以提供Stop()函数。但我什么时候打电话呢?有没有办法自动调用我的Stop函数?

这里的模式是什么?我的应用程序中有很多MyClass插件。

现在我的应用程序在退出时挂起。

2 个答案:

答案 0 :(得分:2)

应用程序挂起的原因是每个默认情况下都会将新线程创建为前台线程。只要您有任何正在运行的前台线程,CLR就会使您的进程保持活动状态。

要删除该线程,只需退出它正在运行的代码即可。这将使线程可用于清理,一旦关闭,该过程也将能够关闭(假设您没有其他前台线程在运行)。

答案 1 :(得分:1)

在C ++中,您通常会显式调用delete运算符。这与在C#中显式调用Stop()方法没有什么不同。

如果您的对象是方法的局部变量,则C ++编译器可以自动生成删除操作符调用。使用using语句很好地映射到C#中的IDisposible:

void SomethingSlow() {
  using (var obj = new MyClass()) {
    // etc..
  }
}

class MyClass : IDisposable {
  private ManualResetEvent mStop = new ManualResetEvent(false);
  public Dispose() {
    mStop.Set();
  }
  // etc...
}

您的线程可能现在不会停止,因为您忘记将_running字段声明为volatile。使用事件可以帮助避免这样的问题。您可以将线程的IsBackground属性设置为true,以防止线程挂起程序终止。这是一个创可贴,而不是修复。