ManualResetEvent を使用してスレッドを同期するアプリケーションを使用しています。FxCop から、それらのオブジェクトを破棄するように言われました。私は同じことを言った次の議論を見つけました:
EventWaitHandle を Dispose() または Close() する必要がありますか?
しかし、ManualResetEvent のインスタンスを破棄するタイミングがわかりません。
次の簡略化されたコードは、問題を示しています。
private void btn_Click(object sender, EventArgs e)
{
var mre = new ManualResetEvent(false);
new Thread(() => this.SetEvent(mre)).Start();
for (int i = 0; i < 10; ++i)
{
new Thread(() => this.WaitFor(mre)).Start();
}
}
private void SetEvent(ManualResetEvent manualResetEvent)
{
Thread.Sleep(10000);
manualResetEvent.Set();
}
private void WaitFor(ManualResetEvent manualResetEvent)
{
manualResetEvent.WaitOne();
}
問題は、ManualResetEvent の複数のインスタンスが存在し、複数のスレッドが各インスタンスを待機していることです。
リスト内のインスタンスを暗記すると、いつ破棄するかわかりません。WaitOne() 呼び出しの後に破棄すると、複数回破棄され、他のスレッドがまだ待機している間に破棄される可能性があります。
イベントを作成したスレッドには、イベントへの参照がありません。この MRE を待っている他のスレッドがあるため、setter-thread はそれを破棄しないでください。前述のように、待機中の各スレッドはそれを破棄できません。
問題は、この ManualResetEvent をいつ破棄する必要があるかということです。