エクスポート (0) 印刷
すべて展開
情報
要求されたトピックは次のとおりです。しかし、このトピックはこのライブラリには含まれていません。

WaitHandle クラス

2013/12/12

共有リソースへの排他アクセスの待機に使用するオペレーティング システム固有のオブジェクトをカプセル化します。

Namespace:  System.Threading
アセンブリ:  mscorlib (mscorlib.dll 内)

public abstract class WaitHandle : IDisposable

WaitHandle 型で公開されるメンバーは以下のとおりです。

  名前説明
プロテクト メソッドWaitHandleWaitHandle クラスの新しいインスタンスを初期化します。
このページのトップへ

  名前説明
パブリック プロパティSafeWaitHandleネイティブ オペレーティング システム ハンドルを取得または設定します。
このページのトップへ

  名前説明
パブリック メソッドClose派生クラスでオーバーライドされると、現在の WaitHandle で保持されているすべてのリソースを解放します。
パブリック メソッドDispose()WaitHandle クラスの現在のインスタンスによって使用されているすべてのリソースを解放します。
プロテクト メソッドDispose(Boolean)派生クラスでオーバーライドされると、WaitHandle によって使用されているアンマネージ リソースを解放し、オプションでマネージ リソースも解放します。
パブリック メソッドEquals(Object)指定した Object が、現在の Object と等しいかどうかを判断します。 (Object から継承されます。)
プロテクト メソッドFinalizeObject がガベージ コレクションで再利用される前に、Object がリソースを解放して他のクリーンアップ操作を実行できるようにします。 (Object から継承されます。)
パブリック メソッドGetHashCode特定の型のハッシュ関数として機能します。 (Object から継承されます。)
パブリック メソッドGetType現在のインスタンスの Type を取得します。 (Object から継承されます。)
プロテクト メソッドMemberwiseClone現在の Object の簡易コピーを作成します。 (Object から継承されます。)
パブリック メソッドToString現在のオブジェクトを表す文字列を返します。 (Object から継承されます。)
パブリック メソッド静的メンバーWaitAll(WaitHandle[])指定した配列内のすべての要素がシグナルを受信するまで待機します。
パブリック メソッド静的メンバーWaitAll(WaitHandle[], Int32)Int32 値を使用して時間間隔を指定し、指定した配列内のすべての要素がシグナルを受信するまで待機します。
パブリック メソッド静的メンバーWaitAll(WaitHandle[], TimeSpan)TimeSpan 値を使用して時間間隔を指定し、指定した配列内のすべての要素がシグナルを受信するまで待機します。
パブリック メソッド静的メンバーWaitAny(WaitHandle[])指定した配列内のいずれかの要素がシグナルを受信するまで待機します。
パブリック メソッド静的メンバーWaitAny(WaitHandle[], Int32)32 ビット符号付き整数を使用して時間間隔を指定し、指定した配列内のいずれかの要素がシグナルを受信するまで待機します。
パブリック メソッド静的メンバーWaitAny(WaitHandle[], TimeSpan)TimeSpan を使用して時間間隔を指定し、指定した配列内のいずれかの要素がシグナルを受信するまで待機します。
パブリック メソッドWaitOne()現在の WaitHandle が信号を受信するまで、現在のスレッドをブロックします。
パブリック メソッドWaitOne(Int32)32 ビット符号付き整数を使用して時間間隔を指定し、現在の WaitHandle がシグナルを受信するまで、現在のスレッドをブロックします。
パブリック メソッドWaitOne(TimeSpan)TimeSpan を使用して時間間隔を指定し、現在のインスタンスがシグナルを受信するまで、現在のスレッドをブロックします。
このページのトップへ

  名前説明
プロテクト フィールド静的メンバーInvalidHandle無効なネイティブ オペレーティング システム ハンドルを表します。このフィールドは読み取り専用です。
パブリック フィールド静的メンバーWaitTimeout待機ハンドルがシグナル状態になる前に WaitAny 操作がタイムアウトになったことを示します。このフィールドは定数です。
このページのトップへ

このクラスは、通常、同期オブジェクトの基本クラスとして使用されます。WaitHandle から派生したクラスは、共有リソースへのアクセスの取得または解放を示すシグナル通知機構を定義しますが、共有リソースへのアクセスを待機している間にブロックするには、WaitHandle から継承したメソッドを使用します。Windows Phone では、AutoResetEvent クラスと ManualResetEvent クラス、およびこれらの基本クラスである EventWaitHandle は、WaitHandle から派生します。

このクラスの静的メソッドを使用して、1 つ以上の同期オブジェクトがシグナルを受信するまでスレッドをブロックします。

スレッド プールの 3 つのスレッド間で作業を分割する方法と、WaitAnyWaitAll の各静的メソッドを使用してサブタスクの完了を待機する方法を、次の例に示します。

この例では、進行状況をユーザー インターフェイスに報告する BackgroundWorker を作成します。BackgroundWorker を使用することによって、WaitAny メソッドと WaitAll メソッドの影響からユーザー インターフェイス スレッドを分離し、ユーザー インターフェイスの応答性を維持します。

BackgroundWorker は、ThreadPool.QueueUserWorkItem メソッドを使用して 3 つのタスクを作成する DoWork メソッドを実行し、各タスクに作業量をランダムに割り当てます。この例では、各タスクに対して、データとスレッド プロシージャを保持する Subtask クラスを定義します。各タスクには、作業の完了時に通知する ManualResetEvent があります。

タスクの開始後、DoWork メソッドが WaitAny(WaitHandle[], Int32) メソッド オーバーロードを使用して、一番短いサブタスクの完了を待機します。このとき、進行状況をユーザー インターフェイスに報告するためのタイムアウトは 250 ミリ秒です。次に、BackgroundWorkerWaitAll(WaitHandle[], Int32) メソッド オーバーロードを使用して、残りのタスクが完了するまで待機します。このときも、進行状況を表示するためのタイムアウトが設定されています。その後、DoWork メソッドが、3 つのタスクすべての結果を使用してレポートを生成します。

メモメモ:

一番短いタスクが最初に完了するとは限りません。スレッド プールのスレッドのすべてが直ちに開始されるとは限りませんし、スケジューラによる処理が異なる場合もあります。

例を開始すると、マウス ボタン イベントがユーザーのクリックを示すように変更され、バックグラウンド タスクの実行中もユーザー インターフェイスが応答します。

メモメモ:

この例を実行するには、「Windows Phone での静的 TextBlock コントロールのあるコード例のビルド」を参照してください。


using System;
using System.Threading;

// The following using statements simplify the supporting code; they are not required 
// for WaitHandle:
using System.Windows.Controls;
using System.Windows.Input;
using System.ComponentModel;

public class Example
{
   private static TextBlock outputBlock;

   public static void Demo(TextBlock outputBlock)
   {
      Example.outputBlock = outputBlock;
      Example.outputBlock.Text = "Click to start the demo.";

      outputBlock.MouseLeftButtonUp += new MouseButtonEventHandler(MouseUpStart);
   }

   private static void MouseUpStart(object sender, MouseEventArgs e)
   {
      // Replace the startup mouse button handler with a handler that 
      // displays a message.
      outputBlock.MouseLeftButtonUp -= new MouseButtonEventHandler(MouseUpStart);
      outputBlock.MouseLeftButtonUp += new MouseButtonEventHandler(MouseUp);

      outputBlock.Text = 
         "Demo is running. The BackgroundWorker waits for the first subtask to complete,\n" +
         "then waits for all subtasks to complete and produces a report.\n" +
         "Click here at any time to show that the user interface is responsive.\n";

      System.ComponentModel.BackgroundWorker worker = new System.ComponentModel.BackgroundWorker();
      worker.DoWork += DoWork;
      worker.WorkerReportsProgress = true;
      worker.ProgressChanged += Progress;
      worker.RunWorkerCompleted += Completed;
      worker.RunWorkerAsync();
   }

   // The only purpose of this mouse button handler is to show that the user
   // interface is responsive while the background tasks are running.
   //
   private static void MouseUp(object sender, MouseEventArgs e)
   {
      outputBlock.Text += "\nMouse clicked.\n";
   }

   private static void DoWork(object sender, DoWorkEventArgs e)
   {
      BackgroundWorker worker = (BackgroundWorker) sender;

      // Divide the "work" into three parts, and queue three tasks to run on
      // threadpool threads. Provide random data for each task.

      Random r = new Random();
      // Keep a list of subtasks and a list of their ManualResetEvent objects.
      System.Collections.Generic.List<Subtask> subtasks = 
                                 new System.Collections.Generic.List<Subtask>();
      System.Collections.Generic.List<WaitHandle> finished = 
                                 new System.Collections.Generic.List<WaitHandle>();

      for(int i = 1; i <= 3; i++)
      {
         Subtask task = new Subtask(i, 3000 + r.Next(4000));
         subtasks.Add(task);
         finished.Add(task.Finished);
         ThreadPool.QueueUserWorkItem(task.DoSubtask);
      }


      // Wait for ANY subtask to complete, and show progress.

      // Create an array of ManualResetEvent wait handles. Each subtask will
      // signal its ManualResetEvent when it is finished.
      WaitHandle[] waitHandles = finished.ToArray();
      int index = WaitHandle.WaitTimeout;

      while (index == WaitHandle.WaitTimeout)
      {
         // Wait for any WaitHandle to be signaled. Use a timeout of 250 milliseconds 
         // to send progress reports. If a timeout occurs, WaitTimeout is returned;
         // if a WaitHandle signals, the array index of the WaitHandle is returned.
         //
         index = WaitHandle.WaitAny(waitHandles, 250);
         worker.ReportProgress(1);
      }


      // In an actual application, the result of the first subtask could be 
      // processed now. Instead, signal the user interface that the first
      // subtask is done.
      worker.ReportProgress(2);


      // Wait for ALL subtasks to complete, and show progress every 1/4 second if
      // the WaitAll times out.

      while (!WaitHandle.WaitAll(waitHandles, 250))
      {
         // If the WaitAll timed out, show progress.
         worker.ReportProgress(3);
      }


      // Generate a report and return it as the result.
      Subtask first = subtasks[index];
      double total = 0.0;

      foreach( Subtask task in subtasks )
      {
         total += task.Result.TotalMilliseconds;
      }

      e.Result = String.Format(
         "Task {0} was the first to complete, with a duration of {1} seconds.\n"
            + "The total duration of all tasks was {2} seconds.\n", 
         first.SubtaskNumber, 
         first.Result.TotalMilliseconds/1000, 
         total/1000);
   }

   private static void Progress(object sender, ProgressChangedEventArgs e)
   {
      if (e.ProgressPercentage == 2)
      {
         outputBlock.Text += "\nFirst subtask is complete.\n";
      }
      else
      {
         outputBlock.Text += ".";
      }
   }

   private static void Completed(object sender, RunWorkerCompletedEventArgs e)
   {
      BackgroundWorker worker = (BackgroundWorker) sender;
      worker.DoWork -= DoWork;
      worker.ProgressChanged -= Progress;
      worker.RunWorkerCompleted -= Completed;

      outputBlock.Text += 
         String.Format("\n{0}\nTo repeat the demo, refresh the page.", e.Result);
   }
}

class Subtask
{
   // Signal this ManualResetEvent when the task is finished.
   internal ManualResetEvent Finished = new ManualResetEvent(false);
   internal int SubtaskNumber;
   internal TimeSpan Result;
   private int data;

   internal Subtask(int number, int data)
   {
      SubtaskNumber = number;
      this.data = data;
   }

   internal void DoSubtask(object state)
   {
      DateTime start = DateTime.Now;
      Thread.Sleep(data);
      // Return a TimeSpan that represents the duration of the task.
      Result = DateTime.Now-start;
      Finished.Set();
   }
}

/* This code produces output similar to the following:

Demo is running. The BackgroundWorker waits for the first subtask to complete,
then waits for all subtasks to complete and produces a report.
Click here at any time to show that the user interface is responsive.
.....
Mouse clicked.
...........
First subtask is complete.
............
Task 3 was the first to complete, with a duration of 3.178 seconds.
The total duration of all tasks was 15.3553943 seconds.

To repeat the demo, refresh the page.
 */


Windows Phone OS

サポート: 8.0, 7.1, 7.0

この型は、スレッド セーフです。

表示:
© 2014 Microsoft