关于manualresetevent的信息
ManualResetEvent 终止状态 和非终止状态什么意思
使用ManualResetEvent.Reset()方法能将ManualResetEvent设置为nonsignaled,未发出信号状态。此时,所有内部代码包含有“ManualResetEvent.waitOne”这句的线程,都会在运行到“ManualResetEvent.waitOne”这句时,发生阻塞,就是停止不动了。直到ManualResetEvent被ManualResetEvent.Set()方法设置为signaled,即变成发出信号状态。阻塞就会消失,那么所有线程都可以越过“ManualResetEvent.waitOne”这句,继续去执行下面的代码。这个类的作用就是去控制其他线程的暂停与继续执行的。
(之前写反了,没注意,现在看到评论,就改好了,谢谢评论的提醒)
manualresetevent.waitone怎么用 c
保证ManualResetEvent 再类A中是公有的;
然后绑定事件 A.ManualResetEvent += doSometime;
A类每次接收数据之后 调用ManualResetEvent(this,EventArgs);
ManualResetEvent和AutoResetEvent的区别
先来讨论ManualResetEvent,讨论过程中我会穿插一些AutoResetEvent的内容,来做对比: ManualResetEvent都可以阻塞一个或多个线程,直到收到一个信号告诉ManualResetEvent不要再阻塞当前的线程。 可以想象ManualResetEvent这个对象内部有一个Boolean类型的属性IsRelease来控制是否要阻塞当前线程。这个属性我们在初始化的时候可以设置它,如ManualResetEvent event=new ManualResetEvent(false);这就表明默认的属性是要阻塞当前线程。 代码举例: ManualResetEvent _manualResetEvent = new ManualResetEvent(false); private void BT_Temp_Click(object sender, RoutedEventArgs e) { Thread t1 = new Thread(this.Thread1Foo); t1.Start(); //启动线程1 Thread t2 = new Thread(this.Thread2Foo); t2.Start(); //启动线程2 Thread.Sleep(3000); //睡眠当前主线程,即调用BT_Temp_Click的线程 _manualResetEvent .Set(); //想象成将IsRelease设为True } void Thread1Foo() { _manualResetEvent .WaitOne(); //阻塞线程1,直到主线程发信号给线程1,告知_menuResetEvent你的IsRelease属性已经为true, //这时不再阻塞线程1,程序继续往下跑 MessageBox.Show("t1 end"); } void Thread2Foo() { _manualResetEvent .WaitOne(); //阻塞线程2,直到主线程发信号给线程1,告知_menuResetEvent你的IsRelease属性已经为true, //这时不再阻塞线程2,程序继续往下跑 MessageBox.Show("t2 end"); } 注意这里ManualResetEvent和AutoResetEvent的一个重要区别: manual的话肯定会给线程1和线程2都发送一个信号,而auto只会随机给其中一个发送信号。 为什么一个叫manual而一个叫auto呢?我想这是很多人的疑问,现在我们就来看这个问题。 刚才_manualResetEvent .Set();的这句话我想大家都明白了,可以看做将IsRelease的属性设置为true.线程1中 _manualResetEvent.WaitOne();接收到信号后不再阻塞线程1。在此之后的整个过程中IsRelease的值都是true.如果 想将IsRelease的值回复成false,就必须再调用_manualResetEvent.Reset()的方法。 如果是_autoResetEvent.set(),那么_autoResetEvent.WaitOne()后会自动将IsRelease的值自动设置为false. 这就是为什么一个叫auto,一个叫manual.
C# AutoResetEvent的使用
C# AutoResetEvent的使用
AutoResetEvent 允许线程通过发信号互相通信。通常,此通信涉及线程需要独占访问的资源。线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前控制资源的线程
通过调用 Set 发出资源可用的信号。
调用 Set 向 AutoResetEvent 发信号以释放等待线程。AutoResetEvent 将保持终止状态,直到一个正在等待的.线程被释放,然后自动返回非终止状态。如果没有任何线程在等待,则状态将无限期地保持为终止状态。
可以通过将一个布尔值传递给构造函数来控制 AutoResetEvent 的初始状态,如果初始状态为终止状态,则为 true;否则为 false。
通俗的来讲只有等myResetEven.Set()成功运行后,myResetEven.WaitOne()才能够获得运行机会;Set是发信号,WaitOne是等待信号,只有发了信号,
等待的才会执行。如果不发的话,WaitOne后面的程序就永远不会执行。下面我们来举一个例子:我去书店买书,当我选中一本书后我会去收费处付钱,
付好钱后再去仓库取书。这个顺序不能颠倒,我作为主线程,收费处和仓库做两个辅助线程,代码如下:
using System;
using System.Linq;
using System.Activities;
using System.Activities.Statements;
using System.Threading;
namespace CaryAREDemo
{
class Me
{
const int numIterations = 550;
static AutoResetEvent myResetEvent = new AutoResetEvent(false);
static AutoResetEvent ChangeEvent = new AutoResetEvent(false);
//static ManualResetEvent myResetEvent = new ManualResetEvent(false);
//static ManualResetEvent ChangeEvent = new ManualResetEvent(false);
static int number; //这是关键资源
static void Main()
{
Thread payMoneyThread = new Thread(new ThreadStart(PayMoneyProc));
payMoneyThread.Name = "付钱线程";
Thread getBookThread = new Thread(new ThreadStart(GetBookProc));
getBookThread.Name = "取书线程";
payMoneyThread.Start();
getBookThread.Start();
for (int i = 1; i = numIterations; i++)
{
Console.WriteLine("买书线程:数量{0}", i);
number = i;
//Signal that a value has been written.
myResetEvent.Set();
ChangeEvent.Set();
Thread.Sleep(0);
}
payMoneyThread.Abort();
getBookThread.Abort();
}
static void PayMoneyProc()
{
while (true)
{
myResetEvent.WaitOne();
//myResetEvent.Reset();
Console.WriteLine("{0}:数量{1}", Thread.CurrentThread.Name, number);
}
}
static void GetBookProc()
{
while (true)
{
ChangeEvent.WaitOne();
// ChangeEvent.Reset();
Console.WriteLine("{0}:数量{1}", Thread.CurrentThread.Name, number);
Console.WriteLine("------------------------------------------");
Thread.Sleep(0);
}
}
}
}
运行结果如下:
AutoResetEvent与ManualResetEvent的区别
他们的用法\声明都很类似,Set方法将信号置为发送状态 Reset方法将信号置为不发送状态WaitOne等待信号的发送。其实,从名字就可以看出一个手动,
一个自动,这个手动和自动实际指的是在Reset方法的处理上,如下面例子:
public AutoResetEvent autoevent=new AutoResetEvent(true);
public ManualResetEvent manualevent=new ManualResetEvent(true);
默认信号都处于发送状态,
autoevent.WaitOne();
manualevent.WaitOne();
如果 某个线程调用上面该方法,则当信号处于发送状态时,该线程会得到信号,得以继续执行。差别就在调用后,autoevent.WaitOne()每次只允许一个线程
进入,当某个线程得到信号(也就是有其他线程调用了autoevent.Set()方法后)后,autoevent会自动又将信号置为不发送状态,则其他调用WaitOne的线程只
有继续等待.也就是说,autoevent一次只唤醒一个线程。而manualevent则可以唤醒多个线程,因为当某个线程调用了set方法后,其他调用waitone的线程
获得信号得以继续执行,而manualevent不会自动将信号置为不发送.也就是说,除非手工调用了manualevent.Reset().方法,则manualevent将一直保持有信号状态,manualevent也就可以同时唤醒多个线程继续执行。如果上面的程序换成ManualResetEvent的话,就需要在waitone后面做下reset。 ;
如何判断manualresetevent处于终止状态
使用ManualResetEvent.set()方法能将ManualResetEvent设置为fasle,非终止状态,此时,所有内部代码包含有“ManualResetEvent.waitOne”这句的线程,都会在运行到“ManualResetEvent.waitOne”这句时,发生阻塞,就是停止不动了。直到ManualResetEvent被ManualResetEvent.reset()方法设置为true,即变成终止状态。阻塞就会消失,那么所有线程都可以越过“ManualResetEvent.waitOne”这句,继续去执行下面的代码。这个类的作用就是去控制其他线程的暂停与继续执行的。