本質的に最初にリセットを呼び出す待機中のメソッドはありますか?
-
29-09-2019 - |
質問
私は、イベントで複数のセット呼び出しを行うことができるAutoreSeteventを使用しています(例外処理)。追加のセットが呼び出される場合があります。したがって、コードがWaitoneイベントで2回目の呼び出しを行うと、ゲートがすでに開いているため、すぐに通過します。
解決策は、Waitoneの直前にリセットを呼び出すことです。よりクリーンなソリューションはありますか、それともこれを行う唯一の方法ですか?例コード:
private void DoSomeWork()
{
Thread thrd = new Thread(new ThreadStart(DoSomeOtherStuff));
thrd.Start();
//mEvt.Reset();
mEvt.WaitOne();
//continue with other stuff
}
private void DoSomeOtherStuff()
{
/* lots of stuff */
mEvt.Set();
}
private void ExceptionTriggerNeedsToBreakOutOfDoSomeWork()
{
mEvt.Set();
}
例外が処理された後、私は再びドソームワークを呼び出す必要がありますが、複数の例外(またはret教ンの例外)でセットが呼び出された可能性があるため、待機中は流れます。
私の解決策は、待機中の前に常にリセットを呼び出すことです。これは、ApproRiate Solution、貧弱なデザイン、またはこのシナリオを処理する異なるタイプのイベントがありますか?
編集:イベントの隣にコメントされたリセット(提案されたソリューション)を移動しました。
解決
私の懸念は、waitone()の前にreset()を呼び出すと、set()が呼び出された場合に問題が発生していることです。これは、set()を呼び出してから、waitone()を押す前にすぐにreset()をヒットした場合に発生する可能性があります。 set()を2回呼び出していても、両方の後にreset()を呼び出すことはないという保証はありません。リリースのメカニズムなしでスレッドをブロックします。
理想的には、try.catch..finallyブロックを実行し、最終的なブロックでset()を呼び出し、例外処理がメソッドに広がることはありません。それはあなたのために働きますか?
Hansは、このシナリオではマルチスレッドが不要であることが正しいです。私の懸念は、あなたが本当にwaitone()への電話で本当にマルチスレッドをしている場合にのみ適用されます。
また、あなたがセットを複数回呼び出していることに関係しています...それは、最初のセットが呼び出されたとき、リソースが本当にロックされたままであることを意味しますか?まだSet()を2回目にすることができれば、共有リソースで動作するコードを実行していると言っています。その場合、CallがWaitone()をブロック解除する必要はありません。
また、MSDNから:
セットメソッドへのすべての呼び出しがスレッドをリリースするという保証はありません。 2つの呼び出しが近づきすぎると、スレッドがリリースされる前に2番目の呼び出しが発生した場合、1つのスレッドのみがリリースされます。 2回目の呼び出しが発生しなかったかのようです。
いずれにせよ、コードは例外をスローするルートに移動するか、完了まで実行する必要があるように思われますが、両方ではありません。つまり、Set()を2回呼び出すべきではありません。
他のヒント
これは本当の問題ではありません。Waitone()コールは自動的にイベントをリセットします。結局のところ、あなたはManualReseTeventではなく、自動測定値を使用しました。ここでのキーフレーズは自動リセットです。
waitone()通話を介して蒸しているのを見るのもかなり正常です。素敵な複数のコアCPUがあります。Start()に電話をかけたときにスレッドがすぐに開始され、ジョブを完了するために数マイクロ秒かかりませんでした。ミリ秒、何であれ、あなたの目の瞬きよりも速い。
おそらくもっと重要なことに、ここでスレッドは必要ありません。 1つを開始してから、それが終了するのを待つことは無意味です。 dosometherstuff()を直接呼び出してください。