您的位置:首页 > 编程语言 > C#

C#线程通信与异步委托

2013-11-18 14:54 127 查看

线程的通知机制

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();
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: