C#多线程等待所有子线程结束的示例

在使用多线程过程中,可能会遇到在一些情况下必须等待子线程全部执行结束后主线程才进行下一步,

做法如下:

 //在使用多线程过程中,可能会遇到在一些情况下必须等待子线程全部执行结束后主线程才进行下一步,做法如下
      List<ManualResetEvent> manualEvents = new List<ManualResetEvent>();//创建线程等待集合
      for (int i = 0; i < 64; i++) //WaitHandles 的数目必须少于或等于 64 个,所以最大线程数为64
      {
        MB m = new MB();//自定义类,用于传参
        m.mre= new ManualResetEvent(false);
        m.ID = i;

        manualEvents.Add(m.mre);
        ThreadPool.QueueUserWorkItem(ThreadMethod, m);
      }
      WaitHandle.WaitAll(manualEvents.ToArray());//等待所有线程结束
      Console.WriteLine("Thread Finished!");
private static void ThreadMethod(object obj)
    {
      MB m = (MB)obj;
      Thread.Sleep(1000);//等待1秒,用于模拟系统在处理事情
      m.mre.Set();//将事件设置为终止状态
      Console.WriteLine("Thread execute:" + m.ID);
    }

以上方法在处理时当线程数超过64时报错 WaitHandles 的数目必须少于或等于 64 个,所以最大线程数为64
解决方法如下:

        using (var countdown = new MutipleThreadResetEvent(list.Count))
        {
          for (int i = 0; i < list.Count; i++)
          {
            //开启N个线程,传递MutipleThreadResetEvent对象给子线程
            Param p = new Param();
            p.countdown = countdown;
            p.Path = pa[i];
            ThreadPool.QueueUserWorkItem(MyHttpRequest, p);
          }

          //等待所有线程执行完毕
          countdown.WaitAll();
        }
public class MutipleThreadResetEvent: IDisposable
  {
    private readonly ManualResetEvent done;
    private readonly int total;
    private long current;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="total">需要等待执行的线程总数</param>
    public MutipleThreadResetEvent(int total)
    {
      this.total = total;
      current = total;
      done = new ManualResetEvent(false);
    }

    /// <summary>
    /// 唤醒一个等待的线程
    /// </summary>
    public void SetOne()
    {
      // Interlocked 原子操作类 ,此处将计数器减1
      if (Interlocked.Decrement(ref current) == 0)
      {
        //当所以等待线程执行完毕时,唤醒等待的线程
        done.Set();
      }
    }

    /// <summary>
    /// 等待所以线程执行完毕
    /// </summary>
    public void WaitAll()
    {
      done.WaitOne();
    }

    /// <summary>
    /// 释放对象占用的空间
    /// </summary>
    public void Dispose()
    {
      ((IDisposable)done).Dispose();
    }
  }

以上就是C#多线程等待所有子线程结束的示例的详细内容,更多关于c# 多线程等待子线程结束的资料请关注我们其它相关文章!

(0)

相关推荐

  • C# 多线程编程技术基础知识入门

    什么是进程? 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程? 线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针.程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数. 什么是多线程? 多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务. 多线程是指程序中包含多个执行流,即在一个程序中

  • C#中的多线程小试牛刀

    前言 昨天在上班时浏览博问,发现了一个问题,虽然自己在 C# 多线程上没有怎么尝试过,看了几遍 CLR 中关于 线程的概念和讲解(后面三章).也想拿来实践实践.问题定义是这样的: 对于多线程不是很懂,面试的时候遇到一个多线程的题,不会做,分享出来,懂的大佬指点一下,谢谢 建一个winform窗体,在窗体中放上一个开始按钮,一个停止按钮,一个文本框,在窗体中声明一个List类型的属性,点击开始按钮后开启10个线程,所有线程同时不间断的给List集合中添加1-10000之间的随机数,要求添加List

  • C#多线程之Semaphore用法详解

    Semaphore:可理解为允许线程执行信号的池子,池子中放入多少个信号就允许多少线程同时执行. private static void MultiThreadSynergicWithSemaphore() { //0表示创建Semaphore时,拥有可用信号量数值 //1表示Semaphore中,最多容纳信号量数值 Semaphore semaphore = new Semaphore(0, 1); Thread thread1 = new Thread(() => { //线程首先WaitO

  • 详解C#多线程编程之进程与线程

    一. 进程 简单来说,进程是对资源的抽象,是资源的容器,在传统操作系统中,进程是资源分配的基本单位,而且是执行的基本单位,进程支持并发执行,因为每个进程有独立的数据,独立的堆栈空间.一个程序想要并发执行,开多个进程即可. Q1:在单核下,进程之间如何同时执行? 首先要区分两个概念--并发和并行 并发:并发是指在一段微小的时间段中,有多个程序代码段被CPU执行,宏观上表现出来就是多个程序能"同时"执行. 并行:并行是指在一个时间点,有多个程序段代码被CPU执行,它才是真正的同时执行. 所

  • 基于C#实现的轻量级多线程队列图文详解

    前言 工作中我们经常会遇到一些一些功能需要实现造作日志,数据修改日志,对于这种业务需求如果我们以同步的方式实现,难免会影响到系统的性能.如下我列出集中解决方案. 使用Thread异步处理. 使用线程池或Task异步处理. 以上两种方案确实能解决我们此场景的需求,但是同时也带来了问题. 第一种方式,使用thread的情况下我们无法控制创建的线程数量,要知道创建线程是一个很耗性能的操作. 第二种方式,使用线程池或者Task我们虽然可以通过设置线程池的最大线程数量来限制线程最大数,但是这个设置由于是全

  • C#中多线程ManualResetEvent 与 AutoResetEvent 区别

    在多线程开发中,时常用到ManualResetEvent 与AutoResetEvent . 它们如同道路交通中的信号灯.两者之间有什么区别呢? 共同点: 均继承EventWaitHandle 接口,因此,均具有以下功能: Reset() //红灯 Set() //绿灯 WaitOne() // 等待信号 不同点: AutoResetEvent 收到 Set 后 , 一次只能执行一个线程,其它线程继续 WaitOne . ManualResetEvent 收到 Set 后,所有处理 WaitOn

  • C#多线程爬虫抓取免费代理IP的示例代码

    这里用到一个HTML解析辅助类:HtmlAgilityPack,如果没有网上找一个增加到库里,这个插件有很多版本,如果你开发环境是使用VS2005就2.0的类库,VS2010就使用4.0,以此类推..........然后直接创建一个控制台应用,将我下面的代码COPY替换就可以运行,下面就来讲讲我两年前做爬虫经历,当时是给一家公司做,也是用的C#,不过当时遇到一个头痛的问题就是抓的图片有病毒,然后系统挂了几次.所以抓网站图片要注意安全,虽然我这里没涉及到图片,但是还是提醒下看文章的朋友. clas

  • c#多线程程序设计实例方法

    相信很多人都了解c#语言,但是对于c#语言编写应用程序的经验不够多,所以经常为没有实例练习而烦恼吧.今天小编给大家介绍下C#里的多线程技术.主要是让大家学会线程的创建和启动方法,理解在线程中如何通过委托和窗体控件交互,同时练习IPAddress类.Dns类.IPHostEntry类的基本用法. 1.打开Microsoft Visual Studio 2010软件,选择新建项目,创建一个名叫ScanComputer的Windows窗体应用程序项目,(当然项目名大家可以自己任意取,这个对我们的实验没

  • C#多线程基础知识汇总

    最近自己写了个小爬虫,里面用到了多线程技术,忽然发现对此技术竟然有些陌生了,于是乎开始疯狂的去问度娘,在此记录下来,以便自己和各位小伙伴们学习. 一.什么是线程 一个应用程序就相当于一个进程,进程拥有应用程序的所有资源进程包括线程,进程的资源被线程共享,但不拥有线程.我们可以打开电脑中的任务管理器,运行的.exe都是一个进程,里面的分支是线程. 二.多线程 多线程其实就是进程中一段并行运行的代码 1. 创建并启动线程 static void Main() { //获取线程Id var threa

  • C#中的多线程超时处理实践方案

    最近我正在处理C#中关于timeout行为的一些bug.解决方案非常有意思,所以我在这里分享给广大博友们. 我要处理的是下面这些情况: 我们做了一个应用程序,程序中有这么一个模块,它的功能向用户显示一个消息对话框,15秒后再自动关闭该对话框.但是,如果用户手动关闭对话框,则在timeout时我们无需做任何处理. 程序中有一个漫长的执行操作.如果该操作持续5秒钟以上,那么请终止这个操作. 我们的的应用程序中有执行时间未知的操作.当执行时间过长时,我们需要显示一个"进行中"弹出窗口来提示用

  • 深入了解c#多线程编程

    一.使用线程的理由 1.可以使用线程将代码同其他代码隔离,提高应用程序的可靠性. 2.可以使用线程来简化编码. 3.可以使用线程来实现并发执行. 二.基本知识 1.进程与线程:进程作为操作系统执行程序的基本单位,拥有应用程序的资源,进程包含线程,进程的资源被线程共享,线程不拥有资源. 2.前台线程和后台线程:通过Thread类新建线程默认为前台线程.当所有前台线程关闭时,所有的后台线程也会被直接终止,不会抛出异常. 3.挂起(Suspend)和唤醒(Resume):由于线程的执行顺序和程序的执行

  • C# FileStream实现多线程断点续传

    一.前言 网上有许多的多线程断点续传操作,但总是写的很云里雾里,或者写的比较坑长.由于这几个月要负责公司的在线升级项目,所以正好顺便写了一下 代码如下: using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; namespace TestCenter { class Program { static void Main(string[] args) { strin

随机推荐