private ManualResetEvent _isServerClosed = new ManualResetEvent(false);
private void StartThreads()
{
//生成ABCD四个线程
for (int i = 0; i < 4; i++) //
{
System.Threading.Thread t = new Thread(new ThreadStart(ReceiveData));
t.Start();
}
}
//停止接收,运行在主线程上.
private void button6_Click(object sender, EventArgs e)
{
_isServerClosed.Set();
}
//运行在新生成的线程上
private void ReceiveData()
{
//等待100毫秒,接受数据,
while (!_isServerClosed.WaitOne(100, false))
{
//接收数据......
for (int i = 0; i < 1000000; i++)
{
////this.richTextBox1.Text += i.ToString() + "\r\n";
//System.Diagnostics.Process.Start("CMD.exe", i.ToString() + "\r\n");
}
}
}
private void button1_Click(object sender, EventArgs e)
{
richTextBox1.Text = "";
button1.Enabled = false;
Mutex1 = new Mutex(true);//Mutex对象(一个调度指令)
Mutex2 = new Mutex(true);
Mutex3 = new Mutex(true);
Mutex4 = new Mutex(true);
Mutex5 = new Mutex(true);
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), "多线程调度例子");//主线程暂停时,更新进度信息
Thread T1 = new Thread(new ThreadStart(Thread1));//定义4个线程
Thread T2 = new Thread(new ThreadStart(Thread2));
Thread T3 = new Thread(new ThreadStart(Thread3));
Thread T4 = new Thread(new ThreadStart(Thread4));
T1.Start();// 使用Mutex.WaitAll()方法等待一个Mutex数组(Mutex4和Mutex5)中的对象全部被释放
T2.Start();// 使用Mutex.WaitOne()方法等待Mutex3的释放
T3.Start();// 使用Mutex.WaitAny()方法等待一个Mutex数组中任意一个对象被释放
T4.Start();// 使用WaitHandle.WaitAll等待所有线程结束
Thread.Sleep(10);
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), "分五个线程调度指令Mutex1--Mutex5");//主线程暂停时,更新进度信息
Thread.Sleep(2000);
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), "主线程中释放Mutex1");//主线程暂停时,更新进度信息
Mutex1.ReleaseMutex(); //线程Thread3结束条件满足
Thread.Sleep(2000);
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), "主线程中释放Mutex3");//主线程暂停时,更新进度信息
Mutex3.ReleaseMutex(); //线程Thread2结束条件满足
Thread.Sleep(2000);
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), "主线程中释放Mutex4");//主线程暂停时,更新进度信息
Mutex4.ReleaseMutex();
Thread.Sleep(2000);
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), "主线程中释放Mutex5");//主线程暂停时,更新进度信息
Mutex5.ReleaseMutex(); //线程Mutex1结束条件满足
button1.Enabled = true;
}
private static Mutex Mutex1, Mutex2, Mutex3, Mutex4,Mutex5;//创建Mutex对象(调度指令)
private static AutoResetEvent Event1 = new AutoResetEvent(false);//线程结束信息灯,未结束false,结束true
private static AutoResetEvent Event2 = new AutoResetEvent(false);
private static AutoResetEvent Event3 = new AutoResetEvent(false);
private AutoResetEvent[] EventS = new AutoResetEvent[] { Event1, Event2, Event3 };//线程组结束信息灯
private delegate void ChangeString(string Txt);//这个代理能异步调用设置文本框(可以多参数)
public void Thread1()
{
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), new object[] { "线程Thread1启动,Mutex.WaitAll,等待Mutex4和Mutex5都释放信号" });//从VS2005开始,给主线程控件附值被认为是不安全的
Mutex[] gMs = new Mutex[2];
gMs[0] = Mutex4;//创建一个Mutex数组作为Mutex.WaitAll()方法的参数
gMs[1] = Mutex5;
Mutex.WaitAll(gMs);//等待Mutex1和Mutex2都被释放
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), "线程Thread1结束");//从VS2005开始,给主线程控件附值被认为是不安全的
Event1.Set(); //线程结束,将Event1设置为有信号状态
}
public void Thread2()
{
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), "线程Thread2启动,Mutex3.WaitOne,等待Mutex3释放信号");//从VS2005开始,给主线程控件附值被认为是不安全的
Mutex3.WaitOne();//等待Mutex3被释放
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), "线程Thread2结束");//从VS2005开始,给主线程控件附值被认为是不安全的
Event2.Set();//线程结束,将Event2设置为有信号状态
}
public void Thread3()
{
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), "线程Thread3启动,Mutex.WaitAny,等待Mutex1和Mutex2中的一个释放信号");//从VS2005开始,给主线程控件附值被认为是不安全的
Mutex[] gMs = new Mutex[2];
gMs[0] = Mutex1;//创建一个Mutex数组作为Mutex.WaitAny()方法的参数
gMs[1] = Mutex2;
Mutex.WaitAny(gMs);//等待数组中任意一个Mutex对象被释放
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), "线程Thread3结束");//从VS2005开始,给主线程控件附值被认为是不安全的
Event3.Set();//线程结束,将Event3设置为有信号状态
}
public void Thread4()
{
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), "线程Thread4启动,WaitHandle.WaitAll,等待所有线程结束");//从VS2005开始,给主线程控件附值被认为是不安全的
WaitHandle.WaitAll(EventS);
richTextBox1.Invoke(new ChangeString(SetrichTextBox1Text), "线程Thread4结束,所有线程结束");//从VS2005开始,给主线程控件附值被认为是不安全的
}
private void SetrichTextBox1Text(string Txt)//此部分实际上是主线程调用的(可以多参数)
{
richTextBox1.Text += Txt + "\r\n";
richTextBox1.Refresh();
}