可能であれば2つの問題を回避するC#のスレッドセーフコードを探しています。
- スレッドオブジェクトがいずれかの時点で破棄されると、スレッドループは適切に終了します。
- 別のクラスまたはフォーム(特にフォーム)で使用される場合、クラスを使用する開発者は、フォームのcloseイベントをフックしてdisposeを呼び出すことを覚えておく必要はありません。例:サーバーのスレッドの正しい仕上げ
スレッドは、次のwhileループを持つメソッドを呼び出しています。
while (!Finished)
{
string request = "";
try
{
//Block until we have a message or we are terminated in dispose **
request = server.Recv(Encoding.Unicode);
//Send a response to the sender so they know we received.
server.Send(request, Encoding.Unicode);
}
catch (Exception e)
{
//Catch a termination error.
if (e.Errno == ETERM)
{
break;
}
}
syncContext.Post(
new SendOrPostCallback(delegate(object state)
{
MessageHandler handler = OnMessage;
if (handler != null)
{
handler(request);
}
}), null);
}
そして、処分は現在そのように見えます。
public void Dispose()
{
Finished = true;
//Cause all blocking message requests and sends to terminate with exception **
FZMQConext.Dispose();
//Wait for the thread to finish up.
FThread.Join();
GC.SuppressFinalize(this);
}
私が見ている問題は次のとおりです。
- スレッドのロールアウトを終了する必要があるため、クラスを破棄しているにもかかわらず、イベントが呼び出される可能性があります。破棄されたと言うのは、try / catchとsyncContext.Post()の間で呼び出されます。これはどれくらい悪いですか?
- このクラスをまとめて、ユーザーがdisposeを呼び出すことを覚えておく必要がないようにする方法はありますか。現在、彼らがいない場合、アプリケーションはスレッドが終了するのを待ってそこに座っていますが、それは決してありません。バックグラウンドスレッドに設定するのは怠惰なようです。