c#等待所有子線程執行完畢方法


當我們在使用線程中,你會發現主線結束后子線程的結果才顯示出來。現在我要等待所以子線程結束,然后在顯示結果,怎么做呢?

方法如下:

1、使用 ManualResetEvent,代碼如下:

using System.Threading;

namespace ThreadStudy
{
     ///   <summary>
    
///  等待所有子線程結束
    
///   </summary>
     class StopAllWaitBySubThread
    {
        List<ManualResetEvent> manualEvents =  new List<ManualResetEvent>();
         public  void Main()
        {
             for ( int i =  0; i <  5; i++)
            {
                ManualResetEvent mre =  new ManualResetEvent( false);
                manualEvents.Add(mre);
                ThreadPool.QueueUserWorkItem(ThreadMethod, mre);
            }
            WaitHandle.WaitAll(manualEvents.ToArray());
            Console.WriteLine( " Thread Finished! ");
        }

         private  void ThreadMethod( object obj)
        {
             // 等待2秒,用於模擬系統在處理事情
            Thread.Sleep( 2000);

            ManualResetEvent mre = (ManualResetEvent)obj;
            mre.Set();
            Console.WriteLine( " Thread execute ");
        }
    }
}

 此種方法線程中只傳遞了信號,那要傳遞參數怎么辦?可以采用類,將信號放在類中來解決,代碼如下。

 

using System.Threading;

namespace ThreadStudy
{
     ///   <summary>
    
///  等待所有子線程結束
    
///   </summary>
     class StopAllWaitBySubThread
    {
        List<ManualResetEvent> manualEvents =  new List<ManualResetEvent>();
         public  void Main()
        {
             for ( int i =  0; i <  5; i++)
            {
                ManualResetEvent mre =  new ManualResetEvent( false);
                manualEvents.Add(mre);
                Param pra =  new Param();
                pra.mrEvent = mre;
                pra.praData = i;
                ThreadPool.QueueUserWorkItem(ThreadMethod, pra);
            }
            WaitHandle.WaitAll(manualEvents.ToArray());
            Console.WriteLine( " Thread Finished! ");
        }

         private  void ThreadMethod( object obj)
        {
            Thread.Sleep( 2000);
            Param pra = (Param)obj;
            pra.mrEvent.Set();
            Console.WriteLine( " Thread execute at {0} ", pra.praData);
        }
    }

     public  class Param
    {
         public ManualResetEvent mrEvent;
         public  int praData;
    }
}

 

2、判斷線程數

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading;

namespace ThreadStudy
{
     ///   <summary>
    
///  判斷當所有子線程執行完畢
    
///   </summary>
     class ThreadPoolStop
    {
         public  void Main()
        {
             for ( int i =  0; i <  5; i++)
            {
                ThreadPool.QueueUserWorkItem( new WaitCallback(ThreadMethod), i);
            }
             int maxWorkerThreads, workerThreads;
             int portThreads;
             while ( true)
            {
                 /*
                 GetAvailableThreads():檢索由 GetMaxThreads 返回的線程池線程的最大數目和當前活動數目之間的差值。
                 而GetMaxThreads 檢索可以同時處於活動狀態的線程池請求的數目。
                 通過最大數目減可用數目就可以得到當前活動線程的數目,如果為零,那就說明沒有活動線程,說明所有線程運行完畢。
                 
*/
                ThreadPool.GetMaxThreads( out maxWorkerThreads,  out portThreads);
                ThreadPool.GetAvailableThreads( out workerThreads,  out portThreads);
                 if (maxWorkerThreads - workerThreads ==  0)
                {
                    Console.WriteLine( " Thread Finished! ");
                     break;
                }
            }
        }

         private  void ThreadMethod( object i)
        {
            //模擬程序運行
            Thread.Sleep(( new Random().Next( 14)) *  1000);
            Console.WriteLine( " Thread execute at {0} ", i.ToString());
        }
    }
}

 

 3、使用Monitor

using System.Threading;

namespace ThreadStudy
{
     class StopAllSubThread
    {
         int _ThreadCount =  5;
         int finishcount =  0;
         object locker =  new  object();
         public  void Main()
        {
             for ( int i =  0; i < _ThreadCount; i++)
            {
                Thread trd =  new Thread( new ParameterizedThreadStart(ThreadMethod));
                trd.Start(i);
            }
             lock (locker)
            {
                 while (finishcount != _ThreadCount)
                {
                    Monitor.Wait(locker); // 等待
                }
            }
            Console.WriteLine( " Thread Finished! ");
        }

         private  void ThreadMethod( object obj)
        {
             // 模擬執行程序
            Thread.Sleep( 3000);
            Console.WriteLine( " Thread execute at {0} ", obj.ToString());
             lock (locker)
            {
                finishcount++;
                Monitor.Pulse(locker);  // 完成,通知等待隊列,告知已完,執行下一個。
            }
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM