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(1, 4)) * 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