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

方法如下:

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. java basic

    //java 声明常量 //final 数据类型 常量名=值; //as: final float PI=3.14f;/ PI=3.14002F //默认浮点为 double //break:跳出多重 ...

  2. web页面背景色控制

    有一道题要实现输入rgb数值,实现更换页面背景色的功能,如下图所示: 答案: <html> <head> <script type="text/javascri ...

  3. 浏览器检测(BrowserDetect.js)

    浏览器检测是在工作中经常用到的,如果只是简单判断当前是什么浏览器的话可以通过window.navigator.useragent这样的js来直接判断就可以了! 但是针对浏览器版本要求比较高的时候,如果 ...

  4. JSON对象的stringify()和parse()方法

    1.stringify() ---- JavaScript对象序列化为JSON字符串 eg1. var book = {title: 'JS', authors: ['Van'], edition:3 ...

  5. 调用windows api 获取系统分辨率

    c++中: int cxScreen,cyScreen; cxScreen=GetSystemMetrics(SM_CXSCREEN); cyScreen=GetSystemMetrics(SM_CY ...

  6. css 多行显示省略号....

    CSS属性如下: white-space: nowrap; overflow: hidden; text-overflow: ellipsis;

  7. oracle删除表的方法

    1. 删除oracle表中的所有数据而不删除表: 语法: TRUNCATE TABLE table_name; 使用这条语句只是删除表中的全部数据,不是删除表,这种方式也叫做截断表,这种方式比使用de ...

  8. sum(iterable[, start]) 对集合求和

    >>> LL [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21] >>> L [3, 4, 5, 6, 7, 8, 9] >> ...

  9. bzoj 2406: 矩阵 上下界网络流判定

    2406: 矩阵 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 138  Solved: 46[Submit][Status][Discuss] De ...

  10. [转载]MongoDB学习(二):数据类型和基本概念

    数据类型 基本数据类型 MongoDB的文件存储格式为BSON,同JSON一样支持往其它文档对象和数组中再插入文档对象和数组,同时扩展了JSON的数据类型.与数据库打交道的那些应用.例如,JSON没有 ...