usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading;usingSystem.Diagnostics;usingSystem.IO;namespacewaitonetest{classProgram {Static voidMain (string[] args) {Program P=NewProgram (); Console.ReadLine (); } Privatehashset<string> m_sallwork;//All Work Privatequeue<string> m_qwaiting;//Wait Queue PrivateAutoResetEvent m_workingevent =NULL;//Work Events PrivateAutoResetEvent m_resumeevent =NULL;//Continuation Events PrivateThread M_monitorthread =NULL;//Monitoring Threads PrivateThread M_workingthread =NULL;//Worker Threads PrivateThread M_patrolthread =NULL;//Patrol Thread PublicProgram () {Console.WriteLine ("Program starting."); M_sallwork=Newhashset<string>(); M_qwaiting=Newqueue<string>(); M_workingevent=NewAutoResetEvent (false); M_resumeevent=NewAutoResetEvent (false); M_monitorthread=NewThread (NewThreadStart (domonitor)); M_workingthread=NewThread (NewThreadStart (DoWork)); M_patrolthread=NewThread (NewThreadStart (Dopatrol)); M_monitorthread.start (); M_workingthread.start (); M_patrolthread.start (); M_workingthread.join (); Console.WriteLine ("Program ending."); } Private voidDoWork () {Console.WriteLine ("Work starting."); Try { Do{m_workingevent.set (); stringfilename =NULL; Try { Lock(m_qwaiting) {filename=M_qwaiting.dequeue (); } } Catch(InvalidOperationException) {Console.WriteLine ("Queue is empty now."); M_resumeevent.waitone ( -);//idle time (this value is less than the patrol period value) Continue; } Catch(Exception e) {Console.WriteLine ("thread-caught Exception-"+e.message); } Console.WriteLine ("Do work .-"+filename); Try{Thread.Sleep (NewRandom (). Next ( +, the)); } Catch(ThreadAbortException) {Console.WriteLine ("thread-caught threadabortexception-resetting."); Lock(m_qwaiting) {m_qwaiting.enqueue (filename);//the failed file is added back to the end of the queue} thread.resetabort (); //Cancel InterruptThread.Sleep ( -);//sleeps 100 milliseconds, allowing external threads to exit by calling interrupt. } Catch(Exception e) {Console.WriteLine ("thread-caught Exception-"+e.message); Lock(m_qwaiting) {m_qwaiting.enqueue (filename);//the failed file is added back to the end of the queue } } } while(true); } Catch(Exception e) {Console.WriteLine ("thread-caught Exception-"+e.message); } Console.WriteLine ("Work ending."); } Private voidDopatrol () {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))//Patrol Cycle{Console.WriteLine ("Work method signaled."); } Else{Console.WriteLine ("Timed out waiting for work method to signal."); M_workingthread.abort (); //Interrupt Work tasks (worker threads are stuck and need to be interrupted to recover, work threads are processed by catching the appropriate exception type) } } while(true); } Catch(Exception e) {Console.WriteLine ("thread-caught Exception-"+e.message); } Console.WriteLine ("Patrol ending."); } Private voidDomonitor () {Console.WriteLine ("Monitor starting."); Try { Lock(m_qwaiting) { for(inti =0; I <Ten; 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 (); //Resume worker threads (because worker threads may be idle waiting) } Do { //generate a work task in a random timeThread.Sleep (NewRandom (). Next ( +,60000)); inti =NewRandom (). Next (1, +); if(!M_sallwork.contains (i.ToString ())) {M_sallwork.add (i.ToString ()); M_qwaiting.enqueue (i.ToString ()); M_resumeevent.set (); //Resume worker threads (because worker threads may be idle waiting) } } while(true); } Catch(Exception e) {Console.WriteLine ("thread-caught Exception-"+e.message); } Console.WriteLine ("Monitor ending."); } }}
Multi-threaded collaboration