多线程调度例子·····················

时间:2022-05-27 23:17:46

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