c#等待全部子線程執行完畢方法

當咱們在使用線程中,你會發現主線結束後子線程的結果才顯示出來。如今我要等待因此子線程結束,而後在顯示結果,怎麼作呢?dom

方法以下:spa

一、使用 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");
        }
    }
}
複製代碼

 此種方法線程中只傳遞了信號,那要傳遞參數怎麼辦?能夠採用類,將信號放在類中來解決,代碼以下。code

 

複製代碼
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;
    }
}
複製代碼

 

二、判斷線程數blog

複製代碼
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());
        }
    }
}
複製代碼

 

 三、使用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); //完成,通知等待隊列,告知已完,執行下一個。
            }
        }
    }
}
複製代碼
相關文章
相關標籤/搜索