假设我在 C++0x 中有一个消息泵类,如下所示(注意,SynchronizedQueue 是 function<void()> 的队列,当您在队列上调用 receive() 并且它为空时,它会阻塞调用线程,直到有一件物品要退货):
class MessagePump
{
private:
bool done_;
Thread* thread_;
SynchronizedQueue queue_;
void Run()
{
while (!done)
{
function<void()> msg = queue_.receive();
msg();
}
}
public:
MessagePump():
done_(false)
{
thread_ = new thread ([=] { this->Run(); } ) );
}
~MessagePump()
{
Send( [&]{ done = true; } );
thread_->join();
}
void Send (function<void()> msg)
{
queue_.send(msg);
}
};
我已将此类转换为 C#,但我对析构函数中的代码有疑问。根据 IDisposable 模式,我应该只提供一个 Dispose() 方法来释放托管和非托管资源。
我应该将 C++ 析构函数代码放入:
- 应用程序退出时客户端需要调用的自定义 CleanUp() 方法?如果客户忘记了怎么办?
- IDisposable 的 Dispose() 方法,以便客户端也可以调用它?但是,如果客户忘记了怎么办?
- 在 C# 终结器方法内部,它会始终执行吗?我读到如果您没有任何非托管资源,则不应包含终结器方法,因为它会损害性能。
- 无处?只是忽略标记 done_ 标志而让 GC 自然处理它,因为 Thread 对象是托管资源?这样线程会被强制中止吗?
我还发现,如果我不将在构造函数中创建的消息泵线程标记为后台线程,我的 MessagePump 对象永远不会被 GC 处理,并且应用程序在退出时只会挂起。这是什么原因?