WaitHandle.WaitOne 方法

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ConsoleTest { //下面代码说明在进程等待后台线程执行完时,如何使用等待句柄阻止进程终止。 class Program { static AutoResetEvent autoEvent = new AutoResetEvent(false); static void Main(string[] args) { Console.WriteLine("Main starting."); ThreadPool.QueueUserWorkItem(new WaitCallback(WorkMethod), autoEvent); //if (autoEvent.WaitOne(1000, false)) // Console.WriteLine("Work method signaled."); //else // Console.WriteLine("Time out waiting for work "+"method to signal."); //Wait for work method to signal. autoEvent.WaitOne(); Console.WriteLine("Main ending."); } static void WorkMethod(object stateInfo) { Console.WriteLine("Work starting."); Thread.Sleep(new Random().Next(100, 2000)); Console.WriteLine("Work ending."); ((AutoResetEvent)stateInfo).Set(); } } }

执行结果:

Main starting.
Work starting.
Work ending.
Main ending.

 

WaitOne:在一个线程MainThread中开启一个新的线程NewThread,在完成初始化并启动NewThread的操作后,调用WaitOne,则MainThread堵塞,直到在NewThread中调用Set,MainThread才继续执行。

 

 

AutoResetEvent 允许线程通过发信号互相通信。通常,此通信涉及线程需要独占访问的资源。

线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前控制资源的线程通过调用 Set 发出资源可用的信号。

调用 SetAutoResetEvent 发信号以释放等待线程。AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。如果没有任何线程在等待,则状态将无限期地保持为终止状态。

可以通过将一个布尔值传递给构造函数来控制 AutoResetEvent 的初始状态,如果初始状态为终止状态,则为 true;否则为 false

通俗的来讲只有等myResetEven.Set()成功运行后,myResetEven.WaitOne()才能够获得运行机会;Set是发信号,WaitOne是等待信号,只有发了信号,等待的才会执行。如果不发的话,WaitOne后面的程序就永远不会执行。

 

下面我们来举一个例子:我去书店买书,当我选中一本书后我会去收费处付钱,
付好钱后再去仓库取书。这个顺序不能颠倒,我作为主线程,收费处和仓库做两个辅助线程,代码如下:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace AutoResetEventDemo { class Program { const int num = 550; static AutoResetEvent myResetEvent = new AutoResetEvent(false); static AutoResetEvent changeEvent = new AutoResetEvent(false); static int number;//这是关键资源 static void PayMoneyProc() { while (true) { myResetEvent.WaitOne(); Console.WriteLine("{0}:数量{1}", Thread.CurrentThread.Name, number); } } static void GetBookProc() { while (true) { changeEvent.WaitOne(); Console.WriteLine("{0}:数量{1}", Thread.CurrentThread.Name, number); Console.WriteLine("------------------------------"); Thread.Sleep(0); } } static void Main() { Thread payMoneyThread = new Thread(new ThreadStart(PayMoneyProc)); payMoneyThread.Name = "付钱线程"; Thread getBookThread = new Thread(new ThreadStart(GetBookProc)); getBookThread.Name = "取书线程"; payMoneyThread.Start(); getBookThread.Start(); for (int i = 1; i < num; i++) { Console.WriteLine("买书线程:数量{0}",i); number = i; myResetEvent.Set(); changeEvent.Set(); Thread.Sleep(0); } payMoneyThread.Abort();//调用此方法通常会终止线程 getBookThread.Abort(); } } }

你可能感兴趣的:(.net)