0

ManualResetEvent は基本的に、他のスレッドに対して「続行するシグナルを受信した場合にのみ続行できます」と伝え、特定の条件が満たされるまで特定のスレッドの実行を一時停止するために使用されます。私が聞きたいのは、while ループを使用して簡単に目的を達成できるのに、なぜ ManualResetEvent が発生するのかということです。次のコンテキストを考慮してください。

public class BackgroundService {

ManualResetEvent mre;
public BackgroundService() {
    mre = new ManualResetEvent(false);
}
public void Initialize() {
    // Initialization
    mre.Set();
}

public void Start() {
    mre.WaitOne();
    // The rest of execution
}
}

にいくらか似ている

public class BackgroundService {

bool hasInitialized;
public BackgroundService() {

}
public void Initialize() {
    // Initialization
    hasInitialized = true;
}

public void Start() {
    while (!hasInitialized)
    Thread.Sleep(100);
    // The rest of execution
}
}

ManualResetEvent が while ループよりも適している特定のコンテキストはありますか?

4

2 に答える 2

3

ManualResetEvent が while ループよりも適している特定のコンテキストはありますか?

絶対。主な理由は 2 つあります。レイテンシと効率です。

スレッドを再度実行するためのコンテキスト切り替えは、スリープ状態に戻るだけの場合に比較的コストがかかります。指定したアプローチでは、hasInitialized設定されている変数に応答するのに平均 50 ミリ秒かかります。まったく応答すると仮定します。 . (明示的なメモリ バリアがないため、実際にはスレッドが変数の変更をまったく認識しない可能性があります。呼び出しThread.Sleepによってメモリ バリアが効果的に追加されると思われますが、保証されていません。) OS/CLR を使用する場合レベルの同期プリミティブを使用すると、スレッドははるかに高速に応答できます。

于 2013-12-09T06:53:50.697 に答える