次のような 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#ファイナライザーメソッド内で常に実行されますか? 管理されていないリソースがない場合は、パフォーマンスが低下するため、ファイナライザー メソッドを含めないでください。
- どこにも?Thread オブジェクトは管理対象リソースであるため、done_ フラグのマークを無視して、GC に自然に処理させるだけですか? この方法でスレッドは強制的に中止されますか?
また、コンストラクター内で作成されたメッセージ ポンプ スレッドをバックグラウンド スレッドとしてマークしないと、MessagePump オブジェクトが GC されず、終了時にアプリケーションがハングすることもわかりました。これの理由は何ですか?