mainFrm という名前の単一のフォームと、実行中のスレッドを保持する objectA というオブジェクトがあるとします。これら 2 つのいずれかが発生すると、私のプログラムは終了するはずです。
(1)。ユーザーが mainFrm の「X」ボタンをクリックします (つまり、mainFrm.FormClosing が発生します)
(2)。objectA でイベント (「connectionClosed」と名付けましょう) が発生します。
したがって、(1)または(2)がトリガーされたとしても、この一連のイベントには常に次のものが含まれている必要があります。
- objectA の基になるスレッドの終了。(objectA内にあるコードでそれらを適切に終了する方法はすでに知っています)
- もちろん、mainFrmのクローズ
この問題を解決する最善の方法は何ですか?
これが私が解決した方法です
この質問がコミュニティに受け入れられなかった理由がわかりません。私はそれがかなり明確で簡単だと思いました。これが私がそれを解決した方法です。これが、私が意図したことをよりよく定義するのにも役立つことを願っています。他に質問がある場合は、お知らせください =)
フォーム クラス:
...
this.FormClosed += objectA.kill;
objectA.connectionClosed +=closeForm;
...
private void closeForm(object sender, FormClosedEventArgs e)
{
try
{
this.Invoke(new MethodInvoker(delegate { this.Close(); }));
}
catch { }
}
objectA のクラス:
...
//connectionClosed is raised in different parts of objectA's threads code
connectionClosed += killClient;
...
public void killClient(object sender, FormClosedEventArgs e)
{
//event should go past this point just once
if (!_connectionClosed)
{
_connectionClosed = true;
try
{
... //close connection killing all threads
}
catch { }
}
}
最初に述べた(1)と(2)のユースケースによると、これが起こっているはずです(私が間違っていなければ)
(1)。ユーザーが「X」ボタンをクリック -> フォームが閉じられる -> formclosed が発生する -> objectA.kill メソッドデリゲートが実行される -> 内部スレッドがいくつかの connectionClosed イベントを発生させ、これにより objectA.kill の実行がさらにトリガーされますが、これはダメージを与えません。 volatile bool _connectionClosed (もちろん、とにかく動作する try/catch があるためですが、そのようなコードを再度実行しない方が理にかなっています) -> objectA.kill の完全な実行のみによってスレッドが終了します -> SUCCESS
(2)。サーバーが接続またはネットワーク エラーを閉じます -> objectA の内部スレッドが接続エラーを検出し、いくつかの connectionClosed イベントを発生させます -> 異なるスレッドが objectA.kill メソッド デリゲートを実行しようとします。-> 一方、メイン フォームでは、closeForm が実行され、フォームが閉じられます -> これにより、別の objectA.kill の実行もトリガーされます (this.FormClosed += _client.killClient; のおかげで) -> 繰り返しますが、_connectionClosed であるため、これは問題ありません。 volatile bool は、1 つのスレッドのみが実際にコードを実行できるようにします (最初にイベントを発生させたスレッド) -> スレッドは、objectA.kill の完全な実行のみによって正常に終了します -> SUCCESS
次のステップは、connectionClosed が 1 回だけ上昇するように、より便利な方法を見つけることです。今すぐググってみます =)