C#,多线程控制ManualResetEvent,AutoResetEvent,Mutex使用方法

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace 线程堵塞测试 { //WaitOne()是ManualResetEvent,AutoResetEvent,Mutex,的线程控制点,如果线程中没有则无控制意义 public partial class Form1 : Form { delegate void FuncDelegate(); public Form1() { InitializeComponent(); } public Thread Acq,Pr; FuncDelegate delegateDisplay; //AutoResetEvent mut; ManualResetEvent stopEventHandle; AutoResetEvent 处理线程循环条件; ManualResetEvent 处理堵塞; Mutex 两线程互斥点; Double A = 0,b=0; static object mythis = new object();//此类中唯一标识,防止与其他线程lock(this)混淆 private void button1_Click(object sender, EventArgs e) { stopEventHandle = new ManualResetEvent(false); 处理线程循环条件 = new AutoResetEvent(false); 处理堵塞 = new ManualResetEvent(false); 两线程互斥点 = new Mutex(); delegateDisplay = new FuncDelegate(DisplayResults); Acq = new Thread(new ThreadStart(AcqRun)); Pr = new Thread(new ThreadStart(PrRun)); Acq.Start(); Pr.Start(); 处理线程循环条件.Reset(); 处理堵塞.Set(); } //获取数据线程 public void AcqRun() { while (true) { Thread.Sleep(0); A++; 处理线程循环条件.Set(); if (stopEventHandle.WaitOne(0, true)) break; //两线程互斥点.WaitOne(); lock (mythis) { textBox2.Invoke(new Action(() => { textBox2.Text = A.ToString(); })); } //两线程互斥点.ReleaseMutex(); } 处理线程循环条件.Reset(); return; } //处理数据线程 public void PrRun() { while (处理线程循环条件.WaitOne()) { //mut.WaitOne(); 处理堵塞.WaitOne(); A = A - 0.5; //做一些事情 处理堵塞.Reset(); //两线程互斥点.WaitOne();//如果不加互斥不能同时访问委托 lock (mythis) { textBox1.Invoke(delegateDisplay); } //两线程互斥点.ReleaseMutex(); if (stopEventHandle.WaitOne(0, true)) break; } } public void DisplayResults() { textBox1.Text = A.ToString(); 处理堵塞.Set(); } //跳出线程 private void button2_Click(object sender, EventArgs e) { stopEventHandle.Set(); } } }
这个时单独演示AutoResetEvent,所谓Auto就是执行一次后自动阻止,下一次的运行
namespace AutoResetEvent_Examples { class MyMainClass { const int numIterations = 100; //重复次数设置多少都无所谓,为让大家看清楚设置了100 static AutoResetEvent myResetEvent = new AutoResetEvent(false);//初始值如果为真,则WaitOne()后面的代码会执行一次 static int number; static void Main() { //创建并开始一个线程。 Thread myReaderThread = new Thread(MyReadThreadProc); myReaderThread.Name = "ReaderThread"; myReaderThread.Start(); myResetEvent.Reset();//直接阻止WaitOne()后面的代码不能执行,即使时AutoResetEvent(true),也不会执行 for (int i = 1; i <= numIterations; i++) { Console.WriteLine("向线程写入值: {0}", i); number = i; //发信号,让WaitOne()后面的代码不能执行一次。 myResetEvent.Set(); //让每次循环当中有些间隔,没有其他作用,可以注释掉 Thread.Sleep(1000); } //终止 myReaderThread.Abort(); } static void MyReadThreadProc() { while (true) { //如果初始化时new AutoResetEvent(true),那么会默认执行一次,然后自动堵塞,如果 myResetEvent.WaitOne(); Console.WriteLine("{0} 读取的值 {1}", Thread.CurrentThread.Name, number); } } } }
浙公网安备 33010602011771号