控制threadpool執行緒的順序啟動 - WaitHandle.WaitAll 方法

本文主要是介绍控制threadpool執行緒的順序啟動 - WaitHandle.WaitAll 方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

[C#.NET][Thread] 執行緒的順序啟動 - WaitHandle.WaitAll 方法

WaitHandle.WaitAll 跟Thread.Join很像,都是執行緒等待,在功能上就是執行緒的順序啟動,如同我之前寫過的 [Thread] 執行緒的順序啟動 - Thread.Join方法,實作過程很簡單只需要注意以下兩點

1.WaitHandle是一個抽像類別所以我們得實體化它的子類別,也就是 ManualResetEvent 類別 或AutoResetEvent 類別,如下所示

static WaitHandle[] waitHandles = new WaitHandle[]     
{        new AutoResetEvent(false),        new AutoResetEvent(false)    
};

 

2.再來,看一下多載清單,WaitHandle.WaitAll方法只收WaitHandle[]參數

image

 


接下來則演練如何實作WaitHandle,我用一個類別將我要的資訊擺進去

 

public class Calculator
{public string Name { get; set; }public long Result { get; set; }private AutoResetEvent _WaitHandle;public AutoResetEvent WaitHandle{get { return _WaitHandle; }set { _WaitHandle = value; }}
}

用戶端的呼叫

 

static WaitHandle[] waitHandles = null;
static object _lock = new object();static void Main(string[] args)
{DateTime dt = DateTime.Now;Console.WriteLine("進入主執行緒");//建立集合List<Calculator> calculator = new List<Calculator>() {new Calculator{Result=0,WaitHandle=new AutoResetEvent(false),Name="NO.1"},new Calculator{Result=0,WaitHandle=new AutoResetEvent(false),Name="NO.2"}};//建立WaitHandle陣列,因為WaitHandle.WaitAll只收陣列waitHandles = new WaitHandle[calculator.Count];for (int i = 0; i < calculator.Count; i++){waitHandles[i] = calculator[i].WaitHandle;}ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), calculator[0]);ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), calculator[1]);//等待這兩隻執行緒完成工作WaitHandle.WaitAll(waitHandles);Console.WriteLine("子執行緒完成,花費時間 ={0})", (DateTime.Now - dt).TotalMilliseconds);Console.ReadKey();
}

模擬大量運算工作

static void DoTask(Object state)
{lock (_lock){if (_isTimeOut)return;Calculator calculator = (Calculator)state;Console.WriteLine("{0} 進入子執行緒", calculator.Name);AutoResetEvent reset = calculator.WaitHandle;for (long i = 0; i < 1000000000; i++){calculator.Result++;}Console.WriteLine("{0} 計算結果 :{1}", calculator.Name, calculator.Result.ToString());Console.WriteLine("{0} 離開子執行緒", calculator.Name);reset.Set();}
} 

執行結果就跟我想的一樣,因為 WaitHandle.WaitAll(waitHandles)的關係,主執行緒乖乖的等待所有執行緒完成工作, 

image


WaitHandle.WaitAll還可以設定等待時間,我們把WaitHandle.WaitAll(waitHandles)改成WaitHandle.WaitAll(waitHandles,2000),表示主執行緒願意等子執行緒2秒。

因為ThreadPool沒有Abort方法所以,我加一個變數_isTimeOut旗標,用來判斷執行緒是否結束工作。

再改裝一下程式碼,

 

static bool _isTimeOut=false; static void Main(string[] args) { …略 //等待這兩隻執行緒完成工作 WaitHandle.WaitAll(waitHandles,2000); _isTimeOut = true; Console.WriteLine("子執行緒完成,花費時間 ={0})", (DateTime.Now - dt).TotalMilliseconds); Console.ReadKey(); } 

static void DoTask(Object state) { lock (_lock) { if (_isTimeOut) return; …略 for (longi = 0; i < 1000000000; i++) { //離開子執行緒旗標 if (_isTimeOut) { Console.WriteLine("{0} 計算結果 :{1}", calculator.Name, calculator.Result.ToString()); Console.WriteLine("{0} 離開子執行緒", calculator.Name); return; } calculator.Result++; } …略 } }

 

執行結果,主執行緒等了2秒後,就不想等了,於是就叫子執行緒停下他的工作。

image


WaitHandle.WaitAny方法就是等待任何一隻執行緒完成工作

static void Main(string[] args)
{…略//等待任一隻執行緒完成工作int index = WaitHandle.WaitAny(waitHandles);_isTimeOut = true;Console.WriteLine("子執行緒完成,花費時間 ={0})", (DateTime.Now - dt).TotalMilliseconds);Console.ReadKey();
}

 

執行結果:可以觀察出當任一執行緒完成工作後則離開所有子執行緒

image

这篇关于控制threadpool執行緒的順序啟動 - WaitHandle.WaitAll 方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/319880

相关文章

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

504 Gateway Timeout网关超时的根源及完美解决方法

《504GatewayTimeout网关超时的根源及完美解决方法》在日常开发和运维过程中,504GatewayTimeout错误是常见的网络问题之一,尤其是在使用反向代理(如Nginx)或... 目录引言为什么会出现 504 错误?1. 探索 504 Gateway Timeout 错误的根源 1.1 后端

MySQL 表空却 ibd 文件过大的问题及解决方法

《MySQL表空却ibd文件过大的问题及解决方法》本文给大家介绍MySQL表空却ibd文件过大的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录一、问题背景:表空却 “吃满” 磁盘的怪事二、问题复现:一步步编程还原异常场景1. 准备测试源表与数据

python 线程池顺序执行的方法实现

《python线程池顺序执行的方法实现》在Python中,线程池默认是并发执行任务的,但若需要实现任务的顺序执行,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋... 目录方案一:强制单线程(伪顺序执行)方案二:按提交顺序获取结果方案三:任务间依赖控制方案四:队列顺序消

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat