C#多线程系列之线程通知_第1页
C#多线程系列之线程通知_第2页
C#多线程系列之线程通知_第3页
C#多线程系列之线程通知_第4页
C#多线程系列之线程通知_第5页
已阅读5页,还剩1页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第C#多线程系列之线程通知AutoRestEvent类用于从一个线程向另一个线程发送通知。

微软文档是这样介绍的:表示线程同步事件在一个等待线程释放后收到信号时自动重置。

其构造函数只有一个:

构造函数里面的参数用于设置信号状态。

构造函数说明AutoResetEvent(Boolean)用一个指示是否将初始状态设置为终止的布尔值初始化AutoResetEvent类的新实例。

真糟糕的机器翻译。

AutoRestEvent类是干嘛的,构造函数的参数又是干嘛的?不着急,我们来先来看看这个类常用的方法:

方法说明Close()释放由当前WaitHandle占用的所有资源。Reset()将事件状态设置为非终止,从而导致线程受阻。Set()将事件状态设置为有信号,从而允许一个或多个等待线程继续执行。WaitOne()阻止当前线程,直到当前WaitHandle收到信号。WaitOne(Int32)阻止当前线程,直到当前WaitHandle收到信号,同时使用32位带符号整数指定时间间隔(以毫秒为单位)。WaitOne(Int32,Boolean)阻止当前线程,直到当前的WaitHandle收到信号为止,同时使用32位带符号整数指定时间间隔,并指定是否在等待之前退出同步域。WaitOne(TimeSpan)阻止当前线程,直到当前实例收到信号,同时使用TimeSpan指定时间间隔。WaitOne(TimeSpan,Boolean)阻止当前线程,直到当前实例收到信号为止,同时使用TimeSpan指定时间间隔,并指定是否在等待之前退出同步域。

一个简单的示例

这里我们编写一个这样的程序:

创建一个线程,能够执行多个阶段的任务;每完成一个阶段,都需要停下来,等待子线程发生通知,才能继续下一步执行。

.WaitOne()用来等待另一个线程发送通知;

.Set()用来对线程发出通知,此时AutoResetEvent变成终止状态;

.ReSet()用来重置AutoResetEvent状态;

classProgram

//线程通知

privatestaticAutoResetEventresetEvent=newAutoResetEvent(false);

staticvoidMain(string[]args)

//创建线程

newThread(DoOne).Start();

//用于不断向另一个线程发送信号

while(true)

Console.ReadKey();

resetEvent.Set();//发生通知,设置终止状态

publicstaticvoidDoOne()

Console.WriteLine("等待中,请发出信号允许我运行");

//等待其它线程发送信号

resetEvent.WaitOne();

Console.WriteLine("\n收到信号,继续执行");

for(inti=0;ii++)Thread.Sleep(TimeSpan.FromSeconds(0.5));

resetEvent.Reset();//重置为非终止状态

Console.WriteLine("\n第一阶段运行完毕,请继续给予指示");

//等待其它线程发送信号

resetEvent.WaitOne();

Console.WriteLine("\n收到信号,继续执行");

for(inti=0;ii++)Thread.Sleep(TimeSpan.FromSeconds(0.5));

Console.WriteLine("\n第二阶段运行完毕,线程结束,请手动关闭窗口");

}

AutoResetEvent对象有终止和非终止状态。Set()设置终止状态,Reset()重置非终止状态。

这个终止状态,可以理解成信号已经通知;非终止状态则是信号还没有通知。

注意,注意终止状态和非终止状态指的是AutoResetEvent的状态,不是指线程的状态。

线程通过调用WaitOne()方法,等待信号;

另一个线程可以调用Set()通知AutoResetEvent释放等待线程。

然后AutoResetEvent变为终止状态。

需要注意的是,如果AutoResetEvent已经处于终止状态,那么线程调用WaitOne()不会再起作用。除非调用Reset()。

构造函数中的参数,正是设置这个状态的。true代表终止状态,false代表非终止状态。如果使用newAutoResetEvent(true);,则线程一开始是无需等待信号的。

在使用完类型后,您应直接或间接释放类型,显式调用Close()/Dispose()或使用using。当然,也可以直接退出程序。

需要注意的是,如果多次调用Set()的时间间隔过短,如果第一次Set()还没有结束(信号发送需要处理时间),那么第二次Set()可能无效(不起作用)。

复杂一点的示例

我们设计一个程序:

Two线程开始处于阻塞状态;线程One可以设置线程Two继续运行,然后阻塞自己;线程Two可以设置One继续运行,然后阻塞自己;

程序代码如下(运行后,请将键盘设置成英文输入状态再按下按键):

classProgram

//控制第一个线程

//第一个线程开始时,AutoResetEvent处于终止状态,无需等待信号

privatestaticAutoResetEventoneResetEvent=newAutoResetEvent(true);

//控制第二个线程

//第二个线程开始时,AutoResetEvent处于非终止状态,需要等待信号

privatestaticAutoResetEventtwoResetEvent=newAutoResetEvent(false);

staticvoidMain(string[]args)

newThread(DoOne).Start();

newThread(DoTwo).Start();

Console.ReadKey();

publicstaticvoidDoOne()

while(true)

Console.WriteLine("\n①按一下键,我就让DoTwo运行");

Console.ReadKey();

twoResetEvent.Set();

oneResetEvent.Reset();

//等待DoTwo()给我信号

oneResetEvent.WaitOne();

Console.ForegroundColor=ConsoleColor.Green;

Console.WriteLine("\nDoOne()执行");

Console.ForegroundColor=ConsoleColor.White;

publicstaticvoidDoTwo()

while(true)

Thread.Sleep(TimeSpan.FromSeconds(1));

//等待DoOne()给我信号

twoResetEvent.WaitOne();

Console.ForegroundColor=ConsoleColor.Yellow;

Console.WriteLine("\nDoTwo()执行");

Console.ForegroundColor=ConsoleColor.White;

Console.WriteLine("\n②按一下键,我就让DoOne运行");

Console.ReadKey();

oneResetEvent.Set();

twoResetEvent.Reset();

}

两个线程具有的功能:阻塞自己、解除另一个线程的阻塞。

用电影《最佳拍档》里面的一个画面来理解。

DoOne、DoTwo轮流呼吸,不能自己控制自己呼吸,但自己能够决定别人呼吸。

你搞我,我搞你,就能相互呼吸了。

当然WaitOne()也可以设置等待时间,如果光头佬(DoOne)耍赖不让金刚(DoTwo)呼吸,金刚等待一定时间后,可以强行荡动天平,落地呼吸。

注意,AutoRestEvent用得不当容易发生死锁。

另外AutoRestEvent使用的是内

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论