Suppose I have a message pump class in C++0x like the following (note, SynchronizedQueue is a queue of function<void()> and when you call receive() on the queue and it is empty, it blocks the calling thread until there is an item to return):
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);
}
};
I have converted this class into C#, but I have a question for the code in the destructor. According to the IDisposable pattern, I should only provide a Dispose() method in order to free managed and unmanaged resources.
Should I put the C++ destructor code into:
- A custom CleanUp() method that the client needs to call when application is exiting? What if the client forgets?
- A Dispose() method of IDisposable so that the client can also call it? But again, what if the client forgets?
- Inside the C# finalizer method so it will always execute? I read that if you do not have any unmanaged resources, you shouldn't include a finalizer method because it hurts performance.
- Nowhere? Just ignore marking the done_ flag and just let GC handle it naturally since the Thread object is a managed resource? Will the thread be forcibly aborted in this way?
I have also found out that if I don't mark the message pump thread created inside the constructor as a background thread, my MessagePump object never gets GC'ed and the application just hangs when it exits. What's the reason for this?