导出 (0) 打印
全部展开
信息
您所需的主题如下所示。但此主题未包含在此库中。

WaitHandle 类

2013/12/13

封装等待对共享资源的独占访问的操作系统特定的对象。

Namespace:  System.Threading
程序集:  mscorlib(位于 mscorlib.dll 中)

public abstract class WaitHandle : IDisposable

WaitHandle 类型公开以下成员。

  名称说明
受保护的方法WaitHandle初始化 WaitHandle 类的新实例。
返回顶部

  名称说明
公共属性SafeWaitHandle获取或设置本机操作系统句柄。
返回顶部

  名称说明
公共方法Close在派生类中被重写时,释放由当前 WaitHandle 持有的所有资源。
公共方法Dispose()释放由 WaitHandle 类的当前实例使用的所有资源。
受保护的方法Dispose(Boolean)在派生类中被重写时,释放由 WaitHandle 使用的非托管资源,也可以根据需要释放托管资源。
公共方法Equals(Object)确定指定的 Object 是否等于当前的 Object (从 Object 继承。)
受保护的方法Finalize允许 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)阻止当前线程,直到当前 WaitHandle 收到信号,同时使用 32 位有符号整数指定时间间隔。
公共方法WaitOne(TimeSpan)阻止当前线程,直到当前实例收到信号,同时使用 TimeSpan 指定时间间隔。
返回顶部

  名称说明
受保护的字段静态成员InvalidHandle表示无效的本机操作系统句柄。此字段为只读。
公共字段静态成员WaitTimeout指示在任何等待句柄终止之前 WaitAny 操作已超时。此字段为常量。
返回顶部

此类通常用作同步对象的基类。从 WaitHandle 派生的类定义一个信号传输机制以指示获取或释放对共享资源的独占访问,但它们使用继承的 WaitHandle 方法在等待访问共享资源时阻止。在 Windows Phone 中,AutoResetEventManualResetEvent 类以及它们的基类 EventWaitHandle 都是从 WaitHandle 派生的。

使用此类的静态方法阻塞一个线程,直到一个或多个同步对象接收到信号。

下面的示例演示如何在三个线程池线程之间划分工作,以及如何使用静态的 WaitAnyWaitAll 方法一直等到子任务完成。

该示例创建一个向用户界面报告进度的 BackgroundWorker。通过使用 BackgroundWorker,该示例使得用户界面线程不受 WaitAnyWaitAll 方法的影响,从而使用户界面能够保持响应能力。

BackgroundWorker 运行一个 DoWork 方法,该方法使用 ThreadPool.QueueUserWorkItem 方法创建三个任务,并为每个任务分配随机的工作量。该示例定义一个 Subtask 类,以保存每个任务的数据和线程过程。每个任务都有一个 ManualResetEvent,当其工作完成时将向该事件发出信号。

启动任务后,DoWork 方法使用 WaitAny(WaitHandle[], Int32) 方法重载等待最短的子任务完成,向用户界面报告进度的超时期限为 250 毫秒。然后 BackgroundWorker 使用 WaitAll(WaitHandle[], Int32) 方法重载一直等到剩余的任务完成,同样关于显示进度也有超时期限。然后,DoWork 方法使用所有三个任务的结果生成一份报告。

说明注意:

最短的任务不一定第一个完成。线程池线程可能不会全部立即启动,计划程序也可能不会同等对待这些线程。

启动示例后,它将更改鼠标按钮事件以显示用户单击,证明用户界面在后台任务执行过程中保持响应。

说明注意:

要运行此示例,请参见生成具有静态 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

Windows Phone

此类型是线程安全的。

显示:
© 2014 Microsoft