ManualResetEvent 类
命名空间:
表示线程同步事件,收到信号时,必须手动重置该事件。 此类不能被继承(密封类sealed)。
关键点:
WaitOne():用于阻塞,触发WaitOne时,下面的代码将阻塞执行,就是等待执行,重载方法 可设置超时时间,默认-1(无限等待)
Set():解除阻塞,WaitOne下面的将解除阻塞,继续执行。
方法
WaitOne() | 阻止当前线程,直到当前 WaitHandle 收到信号。 (继承自 WaitHandle) |
WaitOne(Int32) | 阻止当前线程,直到当前 WaitHandle 收到信号,同时使用 32 位带符号整数指定时间间隔(以毫秒为单位)。 (继承自 WaitHandle) |
WaitOne(Int32, Boolean) | 阻止当前线程,直到当前的 WaitHandle 收到信号为止,同时使用 32 位带符号整数指定时间间隔,并指定是否在等待之前退出同步域。 (继承自 WaitHandle) |
WaitOne(TimeSpan) | 阻止当前线程,直到当前实例收到信号,同时使用 TimeSpan 指定时间间隔。 (继承自 WaitHandle) |
WaitOne(TimeSpan, Boolean) | 阻止当前线程,直到当前实例收到信号为止,同时使用 TimeSpan 指定时间间隔,并指定是否在等待之前退出同步域。 (继承自 WaitHandle) |
Reset() | 将事件状态设置为非终止,从而导致线程受阻。 (继承自 EventWaitHandle) |
Set() | 将事件状态设置为有信号,从而允许一个或多个等待线程继续执行。 (继承自 EventWaitHandle) |
控制台示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ManualResetDemo
{
class Program
{
static void Main(string[] args)
{
Console.SetWindowSize(120, 30);
ManualResetEvent manualResetEvent = new ManualResetEvent(false);
Console.WriteLine("创建三个线程,用于测试手动复位事件:ManualResetEvent");
List<Task> listTask = new List<Task>();
for (int i = 0; i < 3; i++)
{
Task task = new Task(() =>
{
Console.WriteLine($"线程【{Thread.CurrentThread.ManagedThreadId}】使用WaitOne阻塞,WaitOne下面的代码将等待,暂不执行,直到收到Set()信号才往下执行");
manualResetEvent.WaitOne();
Console.WriteLine($"线程【{Thread.CurrentThread.ManagedThreadId}】收到Set()解除阻塞信号,继续往下执行...");
});
listTask.Add(task);
}
//启动三个任务
listTask.ForEach(task => task.Start());
Thread.Sleep(1000);
Console.WriteLine("当线程启用后,按下Y键来 调用Set()以释放所有线程阻塞,WaitOne()以下的才代码继续执行.将阻塞或等待的线程继续往下执行...");
string line = Console.ReadLine();
while (!"Y".Equals(line, StringComparison.CurrentCultureIgnoreCase))
{
Console.WriteLine("请输入Y来释放阻塞,将阻塞或等待的线程继续执行");
line = Console.ReadLine();
}
manualResetEvent.Set();
Thread.Sleep(1000);
Console.WriteLine("下面测试使用Reset()继续阻塞...");
Task.Factory.StartNew(() =>
{
Console.WriteLine($"线程【{Thread.CurrentThread.ManagedThreadId}】第二次使用WaitOne继续阻塞...");
manualResetEvent.WaitOne();
Console.WriteLine($"线程【{Thread.CurrentThread.ManagedThreadId}】继续往下执行,直到完成....");
});
manualResetEvent.Reset();
Thread.Sleep(1000);
Console.WriteLine("下面输入任意内容来解除阻塞...");
Console.ReadLine();
manualResetEvent.Set();
Console.WriteLine("已使用Set()解除阻塞");
Console.ReadLine();
}
}
}