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."); } } }
时间: 2024-10-10 21:50:32