当我们在使用线程中,你会发现主线结束后子线程的结果才显示出来。现在我要等待所以子线程结束,然后在显示结果,怎么做呢?

方法如下:

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); //完成,通知等待队列,告知已完,执行下一个。
            }
        }
    }
}

c#等待所有子线程执行完毕方法的更多相关文章

  1. Java多线程--让主线程等待所有子线程执行完毕

    数据量很大百万条记录,因此考虑到要用多线程并发执行,在写的过程中又遇到问题,我想统计所有子进程执行完毕总共的耗时,在第一个子进程创建前记录当前时间用System.currentTimeMillis() ...

  2. java主线程等待所有子线程执行完毕在执行(常见面试题)

    java主线程等待所有子线程执行完毕在执行(常见面试题) java主线程等待所有子线程执行完毕在执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个 ...

  3. Java主线程等待所有子线程执行完毕再执行解决办法(转)

    方法一: Thread.join()方法,亲测可行,thread.join()方法 Vector<Thread> ts = new Vector<Thread>(); for  ...

  4. netframework中等待多个子线程执行完毕并计算执行时间

    本文主要描述在.netframework中(实验环境.netframework版本为4.6.1)提供两种方式等待多个子线程执行完毕. ManualResetEvent 在多线程中,将ManualRes ...

  5. CountDownLatch用法---等待多个线程执行完才执行

    CountDownLatch用法---等待多个线程执行完才执行 CountDownLatch用法---等待多个线程执行完才执行 CountDownLatch用法---等待多个线程执行完才执行 Coun ...

  6. java并发编程学习:如何等待多个线程执行完成后再继续后续处理(synchronized、join、FutureTask、CyclicBarrier)

    多线程应用中,经常会遇到这种场景:后面的处理,依赖前面的N个线程的处理结果,必须等前面的线程执行完毕后,后面的代码才允许执行. 在我不知道CyclicBarrier之前,最容易想到的就是放置一个公用的 ...

  7. Java主线程在子线程执行完毕后再执行

    一.join() Thread中的join()方法就是同步,它使得线程之间由并行执行变为串行执行. public class MyJoinTest { public static void main( ...

  8. Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执行

    Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执行 Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执 ...

  9. Java多线程--让主线程等待子线程执行完毕

    使用Java多线程编程时经常遇到主线程需要等待子线程执行完成以后才能继续执行,那么接下来介绍一种简单的方式使主线程等待. java.util.concurrent.CountDownLatch 使用c ...

随机推荐

  1. 6.5 k个已排好序链表合并为一个排序链表

    1 建立链表(带哨兵位的)2 建立最小堆方法3 合并已排好序的k个链表 typedef int DataType; //建立链表 class Link { private: struct Node { ...

  2. OpenJudge 2754 八皇后

    1.链接地址: http://bailian.openjudge.cn/practice/2754 2.题目: 总时间限制: 1000ms 内存限制: 65536kB 描述 会下国际象棋的人都很清楚: ...

  3. ThinkPHP3.2 加载过程(一)

    加载过程(官方介绍) : 用户URL请求 调用应用入口文件(通常是网站的index.php) 载入框架入口文件(ThinkPHP.php) 记录初始运行时间和内存开销 系统常量判断及定义 载入框架引导 ...

  4. HTML5之图像处理

    --- 内嵌图像 - drawImage可以绘制图像context.drawImage(image,dx,dy)context.drawImage(image,dx,dy,dw,dh)context. ...

  5. Python3 内建模块 datetime/collections/base64/struct

    datetime 我们先看如何获取当前日期和时间: >>> from datetime import datetime >>> now = datetime.now ...

  6. table隔行换色

    以前做表格隔行换色,是在tr上添加不同的背景色,但在程序开发的过程需要做判断,不够方便,而且生成的代码也比较多,现在的需求逐渐修改为JQ去控制简洁的表格去显示隔行换色 <script type= ...

  7. Sublime Text3快捷键一览表

    选择类 Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本. Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同文本进行同时编辑.举个栗子:快速选中并更改所有相同的变量名.函数 ...

  8. jQuery的基本信息。以及入门Demo

    javascript目前最流行的框架jQuery,它是轻量级的js库 ,它兼容CSS3,还兼容各种浏览器.jQuery的作者的核心理念就是write less,do more(写得更少,做得更多).他 ...

  9. python引入导入自定义模块和外部文件

    参考:http://blog.csdn.net/devil_2009/article/details/15816237 项目中想使用以前的代码,或者什么样的需求致使你需要导入外部的包 如果是web 下 ...

  10. Oracle表添加主键、外键

    1.创建表的同时创建主键约束 (1)无命名 create table student ( studentid int primary key not null, studentname varchar ...