C#线程通信与异步委托
线程的通知机制
AutoResetEvent是线程实现通知操作的重要方法。通常,AutoResetEvent用于通知正在等待线程已发生事件,允许线程通过发信号互相通信。
AutoResetEvent时间对象提供了给我们可以控制线程执行的先后顺序,他的常用方法:
Set设置并发送信号
Reset重置信号,也就是使信号无效
WaitOne等待一个信号
WaitAny静态方法,等待一个信号数组,信号数组里面有任何信号都可以,否则等待
WaitAll静态方法,等待一个i额信号数组,信号数组里面的信号全部到齐才可以,否则等待
创建一个AutoResetEvent对象,构造方法里面需要带一个bool类型的参数,
AutoResetEvent myResetEvent = new AutoResetEvent(false);
这个参数如果是false表示时间开始是无信号状态的,当参数为true表示创建的时间开始是有信号的,就相当于使用false参数创建时间后立即设定了Set方法。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace AutoResetEventTest { class Program { static AutoResetEvent myResetEvent = new AutoResetEvent(false); static int number; static void Main(string[] args) { Thread t = Thread.CurrentThread; t.Name = "写线程"; Thread myReaderThread = new Thread(MyReadThreadProc); myReaderThread.Name = "读线程"; myReaderThread.Start(); for (int i = 0; i < 10; i++) { Console.WriteLine("{0}写的值是{1}", t.Name, i); number = i; myResetEvent.Set(); Thread.Sleep(1); } myReaderThread.Abort(); } static void MyReadThreadProc() { while (true) { myResetEvent.WaitOne(); Console.WriteLine("{0}读到的值是{1}", Thread.CurrentThread.Name, number); } } } }
例程2
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace AutoResetEventTest { class Program { static void Main(string[] args) { Person p = new Person(); Thread th1 = new Thread(p.GetCar); th1.Start(); Thread th2 = new Thread(p.GetHome); th2.Start(); Thread th3 = new Thread(p.GetWife); th3.Start(); AutoResetEvent.WaitAll(p.autoEvents); p.ShowHappiness(); } } public class Person { public AutoResetEvent[] autoEvents; public Person() { autoEvents = new AutoResetEvent[] { new AutoResetEvent(false), new AutoResetEvent(false), new AutoResetEvent(false) }; } public void GetCar() { Console.WriteLine("捡到宝马"); autoEvents[0].Set(); } public void GetHome() { Console.WriteLine("赚到房子"); autoEvents[1].Set(); } public void GetWife() { Console.WriteLine("骗到老婆"); autoEvents[2].Set(); } public void ShowHappiness() { Console.WriteLine("好成功哦,好幸福!!!~~~"); } } }
例程3 异步回调
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace AutoResetEventTest { class Program { public delegate int TaskDelegate(object obj, int ms); public static int GouDui(object obj, int ms) { Thread t = Thread.CurrentThread; t.Name = "灰太狼"; Console.WriteLine("老板给了{0}元,让伟大的{1}来勾引你,识相的话赶紧上钩", obj.ToString(), t.Name); Thread.Sleep(ms); return 3000; } static void TakesAWhileCompleted(IAsyncResult ar) { //判断IAsyncResult对象是否有效,为空则抛出异常 if(ar == null) { throw new ArgumentNullException("ar"); } //将ar对象中AsyncState属性强类型转换为TaskDelegate委托类型 TaskDelegate d1 = ar.AsyncState as TaskDelegate; //跟踪检查d1是否有效,如果无效则显示提示消息 System.Diagnostics.Trace.Assert(d1 != null,"无效的对象类型"); //执行委托方法,并将结果交给变量result int result = d1.EndInvoke(ar); Console.WriteLine("结果泡了{0}个漂漂的mm",result); } static void Main(string[] args) { Thread t1 = Thread.CurrentThread; t1.Name = "单行道酒吧"; Console.WriteLine("去{0}给我勾搭几个mm回来!超时每秒抠你100块工资", t1.Name); //为委托指定执行方法 TaskDelegate t = GouDui; //使用魏国的BeginInvoke方法为所委托的方法赋值,并将执行结果交给IasyncResult接口 IAsyncResult ir = t.BeginInvoke(600000, 1000 * new Random().Next(5), TakesAWhileCompleted, t); //Thread.Sleep(2000); //int i = 0; //while (!ir.IsCompleted) //{ // i++; // Console.WriteLine(i.ToString()); // //方法1 // //Thread.Sleep(100); // //方法2 // if (ir.AsyncWaitHandle.WaitOne(100, false)) // { // Console.WriteLine("怎么还不回来,再扣就把钱扣完了!"); // break; // } //} ////获取委托方法执行后返回的值 //int result = t.EndInvoke(ir); //Console.WriteLine("报告老板,我一共给你勾兑了{0}个超级mm", result.ToString()); //if (i >= 1) //{ // Console.WriteLine("非常好,课时你耽误了{0}个小时,所以扣除你{1}块的报酬", i.ToString(), (100 * i).ToString()); //} //else //{ // Console.WriteLine("小伙子不错哦。哥很欣赏你!"); //} Console.ReadKey(); } } }