• 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); //完成,通知等待队列,告知已完,执行下一个。
                }
            }
        }
    }
    复制代码
  • 相关阅读:
    SharePoint添加列表
    js求和
    经典.net面试题目
    sharepoint常见操作
    添加webpart时出现“此网页上的某个Web部件或Web表单控件无法显示或导入。该类型未注册为安全类型 。”
    关于js中"window.location.href"、"location.href"、"parent.location.href"、"top.location.href"的用法
    RegisterStartupScript,RegisterClientScriptBlock,Response.Write 简单说明区别
    jquery中的ready函数与window.onload谁先执行
    TreeView的TreeNode点击展示展开和收缩的效果
    如何让 TreeView 的节点不要生成 超级 链接
  • 原文地址:https://www.cnblogs.com/zhangchenliang/p/9147827.html
Copyright © 2020-2023  润新知