线程的通知机制

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

C#线程通信与异步委托的更多相关文章

  1. c#线程之异步委托begininvoke、invoke、AsyncWaitHandle.WaitOne 、异步回调

    单靠自己看书学总是会走很多弯路,任何人也不列外,有些时候自己遇到的很多问题,其它别人在很久之前也可能遇到过,上网查查可以走很大捷径,对自己的学习有很大帮助,刚开始弄线程这块,一开始只是看书,很多东西都 ...

  2. .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法

    1.多线程简单使用(1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程(2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线 ...

  3. C#基础:线程之异步委托

    线程:是程序中独立的指令流.在我们熟悉的Visual Studio编辑器中输入C# 代码的时候,系统会自动分析代码,提示你输入的代码出现的各种错误,这是一个后台线程完成的. 创建线程的一种简单的方式就 ...

  4. C#基础之--线程、任务和同步:一、异步委托

    创建线程的一种简单方式是定义一个委托,并异步调用它.委托是方法的类型安全的引用. Delegate还支持异步地调用方法.在后台Delegate类会创建一个执行任务的线程. 为了说明委托的异步特性,从一 ...

  5. 使用异步委托执行线程(delegate)

    由于异步委托产生的线程与应用程序主线程是分开执行的,若主线程要获取异步委托线程的结果,则主线程需要等待异步委托的执行结果. BeginInvoke是Delegate类型的一个方法,它的返回类型为IAs ...

  6. c#并行任务多种优化方案分享(异步委托)

    遇到一个多线程任务优化的问题,现在解决了,分享如下. 假设有四个任务: 任务1:登陆验证(CheckUser) 任务2:验证成功后从Web服务获取数据(GetDataFromWeb) 任务3:验证成功 ...

  7. C#固定时间执行指定事件(观察者模式+异步委托)

    最近有个项目需要每天固定的时间去执行指定的事件,发现网上关于这样的文章比较少,而且比较散.通过学习了几篇文章后终于实现了这个功能,在此也特别感谢这些文章的作者们,这也是我第一次在园子里面发文章,望多指 ...

  8. 也来说说C#异步委托(转)

    原文地址: http://www.cnblogs.com/lxblog/archive/2012/12/11/2813893.html 前些日子,看到园子里面有人用老王喝茶的例子讲解了一下同步和异步, ...

  9. C#实现异步编程的两个简单机制(异步委托&定时器)及Thread实现多线程

    创建线程的常用方法:异步委托.定时器.Thread类 理解程序.进程.线程三者之间的区别:简而言之,一个程序至少有一个进程,一个进程至少有一个线程进程就是在内存中运行的程序(即运行着的程序):一个进程 ...

随机推荐

  1. 乐1S 5.8(Android 6.0) 刷第三方recovery并刷入root权限

    说明 我的是 乐视1S, 系统为EUI 5.8 (powered by Android 6.0) 使用的是 superSu来root, 你可以到这里下载 文件 *下载 Recovery Flashab ...

  2. 自发行python版本制作(二)编译

    本系列文章第二篇主要说明windows环境的编译环境搭建以及编译过程. 编译环境选择: 1.选用作神一样存在的Microsoft Visual C++ Compiler for Python 2.7为 ...

  3. H5+CSS3做图片轮播滚动效果

    HTML代码部分: <div id="wrap"> <ul id="list"> <li>10</li> < ...

  4. Xamarin.Forms listview中的button按钮,实现带着参数返回上一级页面

    今天在做列表显示的时候遇到一个问题,就是在ListView中如何才能让一个button的按钮工作并且包含参数呢? 其实有点类似于rep里的控件无法起获取一样.在Xamarin中,当你button绑定事 ...

  5. Hibernate的关联映射

    单向N-1关联 <many-to-one> 单向N-1关系,比如多个人对应同一个住址,只需要从人实体端找到对应的住址实体,无须关系某个地址的全部住户.程序在N的一端增加一个属性,该属性引用 ...

  6. libevent源码分析:listener

    listener是libevent封装的一个方便生成监听者的一组结构和函数,其中包括: /* * Copyright (c) 2000-2007 Niels Provos <provos@cit ...

  7. [LeetCode_2] Add Two Numbers

    LeetCode: 2. Add Two Numbers /** * Definition for singly-linked list. * struct ListNode { * int val; ...

  8. Keras

    sudo pip install keras --安装 新建一个文件,里面存储的数据:第一列是属性,第二列是类别 11220044 011220044 011220044 011220033 1112 ...

  9. SQL的多表连接查询

    SQL的多表连接查询 多表连接查询具有两种规范,SQL92和SQL99规范. SQL92规范支持下列多表连接查询: (1)等值连接: (2)非等值连接: (3)外连接: (4)广义笛卡尔积: SQL9 ...

  10. linux内核追踪——find_next_bit函数详详详解

    写在前面 宗旨:把话说清楚,把道理讲透彻. 约定:所有代码均来自Linux内核2.6.24版. 建议:本文介绍得十分详细,但也略显繁琐,读者可以先看“Ⅴ.总结”部分带注释的源码,如果哪里不清楚,再回头 ...