线程的通知机制
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();
} }
}