• 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); //完成,通知等待队列,告知已完,执行下一个。
                }
            }
        }
    }
  • 相关阅读:
    Javascript的异步和回调
    JS-使用工厂方法创建对象
    PHPUnit使用教程——PHP环境变量+x-debug+composer+phpunit配置安装(超详细!)
    JQuery 纵向二级菜单与对齐方式
    图像映射<map>、<area>
    打开另一个窗口
    多行文本省略号
    replace 正则
    jquery each用法
    li前面的原点或者方的样式修改html中列表项li所显示的圆点的颜色?,以及相关样式的设定
  • 原文地址:https://www.cnblogs.com/asdyzh/p/9824418.html
Copyright © 2020-2023  润新知