C#マルチスレッド(7):手動スレッド通知

3627 ワード

目次
  • と例
  • の区別
  • ManualResetEventクラス
  • ManualResetEventSlim

  • 違いと例


    AutoResetEventとManualResetEventはよく似ています.両者の違いは,前者が自動(Auto),後者が手動(Manua)であることである.
    次の例を実行してから、両者の違いをテストすることができます.
    AutoResetEventの例:
        class Program
        {
            //  
            private static AutoResetEvent resetEvent = new AutoResetEvent(false);
    
            static void Main(string[] args)
            {
                //  
                new Thread(DoOne).Start();
    
                //  
                while (true)
                {
                    Console.ReadKey();
                    resetEvent.Set();           //  , 
                }
            }
    
            public static void DoOne()
            {
                Console.WriteLine("①  , ");
                resetEvent.WaitOne();
    
                Console.WriteLine("②  , ");
    
                resetEvent.WaitOne();
                Console.WriteLine("③  , ");
                
                // ...
    
                Console.WriteLine(" ");
            }
        }
    

    ManualResetEventクラスの例:
        class Program
        {
            private static ManualResetEvent resetEvent = new ManualResetEvent(false);
            static void Main(string[] args)
            {
                new Thread(DoOne).Start();
                //  
                while (true)
                {
                    Console.ReadKey();
                    resetEvent.Set();           //  , 
                }
            }
    
            public static void DoOne()
            {
                Console.WriteLine(" , ");
                resetEvent.WaitOne();
    
                //  , 
                resetEvent.WaitOne();
                resetEvent.WaitOne();
                resetEvent.WaitOne();
                resetEvent.WaitOne();
                resetEvent.WaitOne();
                Console.WriteLine(" ");
            }
        }
    

    AutoResetEventオブジェクトは.WaitOne()メソッドで信号待ちが完了すると自動的に非終端状態にリセットされるため、高速料金所の自動シャッターに相当し、1台の車が通過すると機械が自動的にシャッターを切る.
    ManualResetEventは人工シャッターに相当し、開いた後に人工シャッターを書く.そうしないとシャッターはずっと開いている.
    ManualResetEventは主により柔軟なスレッド信号伝達シーンに用いられる.

    ManualResetEventクラス


    スレッド同期イベントを表し、信号を受信したときに次回も有効にするには、手動でイベントをリセットする必要があります.
    ManualResetEventクラスはAutoManualResetEventクラスに非常に近いので、ここでは省略します.
    これらの違いは主に次のとおりです.
    AutoResetEventクラスは、Set()ごとにWaitOne()をスキップします. になるので、次回WaitOne()に会ったら待ち続けます.
    ManualResetEvent類は、Set()以降、 にはならないので、いったんSet()を使用すると、一路開放され、これ以上待つことはありません.
    構造関数は次のとおりです.
    コンストラクタ
    説明
    ManualResetEvent(Boolean)
    初期状態が終了に設定されているかどうかを示すブール値を使用して、ManualResetEventクラスの新しいインスタンスを初期化します.
    一般的な方法は次のとおりです.
    方法
    説明
    Close()
    現在のWaitHandleによって使用されているすべてのリソースを解放します.
    Reset()
    イベントステータスを非終了に設定すると、スレッドがブロックされます.
    Set()
    イベントステータスを信号に設定して、1つ以上の待機スレッドが実行されるようにします.
    WaitOne()
    現在のWaitHandleが信号を受信するまで、現在のスレッドをブロックします.
    WaitOne(Int32)
    現在のWaitHandleが信号を受信するまで、現在のスレッドをブロックし、32ビットバンドシンボル整数を使用して時間間隔(ミリ秒単位)を指定します.
    WaitOne(Int32, Boolean)
    現在のWaitHandleが信号を受信するまで、現在のスレッドをブロックし、32ビットバンドシンボル整数を使用して時間間隔を指定し、待機する前に同期ドメインを終了するかどうかを指定します.
    WaitOne(TimeSpan)
    現在のインスタンスが信号を受信するまで、現在のスレッドをブロックし、TimeSpanを使用して時間間隔を指定します.
    WaitOne(TimeSpan, Boolean)
    現在のインスタンスが信号を受信するまで現在のスレッドをブロックし、TimeSpanを使用して時間間隔を指定し、待機する前に同期ドメインを終了するかどうかを指定します.

    ManualResetEventSlim


    ManualResetEventSlimは、ManualResetEventと比較して、待ち時間が非常に短く、イベントがプロセス境界を越えないと予想される場合に使用して、ManualResetEventよりも優れたパフォーマンスを得ることができます.
    コードの使用から見ると、何の違いもありません.主に性能の下で、両者の異なるシーンを考慮します.
    ここでは、この2つのタイプについては説明しません.