私はMSDNでAutoResetEventのドキュメントを読んでいて、警告に従うとちょっと気になります。
「重要:Setメソッドへのすべての呼び出しがスレッドを解放するという保証はありません。2つの呼び出しが近すぎるため、スレッドが解放される前に2番目の呼び出しが発生すると、1つのスレッドのみが解放されます。まるで2番目の呼び出しは発生しませんでした。また、待機中のスレッドがなく、AutoResetEventがすでに通知されているときにSetが呼び出された場合、呼び出しは効果がありません。」
しかし、この警告は基本的に、そのようなスレッド同期技術を使用する理由そのものを殺します。たとえば、私は仕事を保持するリストを持っています。そして、リストにジョブを追加するプロデューサーは1人だけです。私には消費者(複数)がいて、リストから仕事を得るのを待っています..このようなもの..
プロデューサー:
void AddJob(Job j)
{
lock(qLock)
{
jobQ.Enqueue(j);
}
newJobEvent.Set(); // newJobEvent is AutoResetEvent
}
消費者
void Run()
{
while(canRun)
{
newJobEvent.WaitOne();
IJob job = null;
lock(qLock)
{
job = jobQ.Dequeue();
}
// process job
}
}
上記の警告が当てはまる場合、2つのジョブを非常にすばやくキューに入れると、1つのスレッドだけがジョブを取得しますね。私は、Setがアトミックである、つまり次のことを行うと想定していました。
- イベントを設定する
- スレッドが待機している場合は、1つのスレッドを選択してウェイクアップします
- イベントをリセットする
- 選択したスレッドを実行します。
だから私は基本的にMSDNの警告について混乱しています。有効な警告ですか?