多线程协同

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.IO;

namespace WaitOneTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();

            Console.ReadLine();
        }

        private HashSet<string> m_sAllWork; // 所有工作
        private Queue<string> m_qWaiting; // 等待队列
        private AutoResetEvent m_WorkingEvent = null; // 工作事件
        private AutoResetEvent m_ResumeEvent = null; // 继续事件
        private Thread m_MonitorThread = null; // 监控线程
        private Thread m_WorkingThread = null; // 工作线程
        private Thread m_PatrolThread = null; // 巡逻线程

        public Program()
        {
            Console.WriteLine("Program starting.");

            m_sAllWork = new HashSet<string>();
            m_qWaiting = new Queue<string>();
            m_WorkingEvent = new AutoResetEvent(false);
            m_ResumeEvent = new AutoResetEvent(false);
            m_MonitorThread = new Thread(new ThreadStart(DoMonitor));
            m_WorkingThread = new Thread(new ThreadStart(DoWork));
            m_PatrolThread = new Thread(new ThreadStart(DoPatrol));
            m_MonitorThread.Start();
            m_WorkingThread.Start();
            m_PatrolThread.Start();
            m_WorkingThread.Join();

            Console.WriteLine("Program ending.");
        }

        private void DoWork()
        {
            Console.WriteLine("Work starting.");
            try
            {
                do
                {
                    m_WorkingEvent.Set();
                    string filename = null;
                    try
                    {
                        lock (m_qWaiting)
                        {
                            filename = m_qWaiting.Dequeue();
                        }
                    }
                    catch (InvalidOperationException)
                    {
                        Console.WriteLine("Queue is empty now.");
                        m_ResumeEvent.WaitOne(2000); // 空闲时间(该值要小于巡逻周期值)
                        continue;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Thread - caught Exception - " + e.Message);
                    }
                    Console.WriteLine("Do work. - " + filename);
                    try
                    {
                        Thread.Sleep(new Random().Next(1000, 5000));
                    }
                    catch (ThreadAbortException)
                    {
                        Console.WriteLine("Thread - caught ThreadAbortException - resetting.");
                        lock (m_qWaiting)
                        {
                            m_qWaiting.Enqueue(filename); // 失败的文件加回队列末尾
                        }
                        Thread.ResetAbort(); // 取消中断
                        Thread.Sleep(100); // 睡眠100毫秒,允许外部通过调用Interrupt退出线程。
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Thread - caught Exception - " + e.Message);
                        lock (m_qWaiting)
                        {
                            m_qWaiting.Enqueue(filename); // 失败的文件加回队列末尾
                        }
                    }
                } while (true);
            }
            catch (Exception e)
            {
                Console.WriteLine("Thread - caught Exception - " + e.Message);
            }
            Console.WriteLine("Work ending.");
        }

        private void DoPatrol()
        {
            Console.WriteLine("Patrol starting.");

            try
            {
                do
                {
                    Console.WriteLine("Wait for work method to signal.");
                    // Wait for work method to signal.
                    if (m_WorkingEvent.WaitOne(4000)) // 巡逻周期
                    {
                        Console.WriteLine("Work method signaled.");
                    }
                    else
                    {
                        Console.WriteLine("Timed out waiting for work method to signal.");
                        m_WorkingThread.Abort(); // 中断工作任务(工作线程被卡住,需要中断来恢复,工作线程中通过抓捕相应异常类型进行处理)
                    }
                } while (true);
            }
            catch (Exception e)
            {
                Console.WriteLine("Thread - caught Exception - " + e.Message);
            }

            Console.WriteLine("Patrol ending.");
        }

        private void DoMonitor()
        {
            Console.WriteLine("Monitor starting.");

            try
            {
                lock (m_qWaiting)
                {
                    for (int i = 0; i < 10; i++)
                    {
                        if (!m_sAllWork.Contains(i.ToString()))
                        {
                            m_sAllWork.Add(i.ToString());
                            m_qWaiting.Enqueue(i.ToString());
                        }
                    }
                    if (m_qWaiting.Count > 0)
                        m_ResumeEvent.Set();  // 恢复工作线程(因为工作线程可能处于空闲等待)
                }
                do
                {
                    // 随机时间内产生一个工作任务
                    Thread.Sleep(new Random().Next(1000, 60000));
                    int i = new Random().Next(1, 1000);
                    if (!m_sAllWork.Contains(i.ToString()))
                    {
                        m_sAllWork.Add(i.ToString());
                        m_qWaiting.Enqueue(i.ToString());
                        m_ResumeEvent.Set(); // 恢复工作线程(因为工作线程可能处于空闲等待)
                    }
                } while (true);
            }
            catch (Exception e)
            {
                Console.WriteLine("Thread - caught Exception - " + e.Message);
            }

            Console.WriteLine("Monitor ending.");
        }
    }
}

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。