控制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

相关文章

PyTorch核心方法之state_dict()、parameters()参数打印与应用案例

《PyTorch核心方法之state_dict()、parameters()参数打印与应用案例》PyTorch是一个流行的开源深度学习框架,提供了灵活且高效的方式来训练和部署神经网络,这篇文章主要介绍... 目录前言模型案例A. state_dict()方法验证B. parameters()C. 模型结构冻

springboot控制bean的创建顺序

《springboot控制bean的创建顺序》本文主要介绍了spring-boot控制bean的创建顺序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录1、order注解(不一定有效)2、dependsOn注解(有效)3、提前将bean注册为Bea

Python字符串处理方法超全攻略

《Python字符串处理方法超全攻略》字符串可以看作多个字符的按照先后顺序组合,相当于就是序列结构,意味着可以对它进行遍历、切片,:本文主要介绍Python字符串处理方法的相关资料,文中通过代码介... 目录一、基础知识:字符串的“不可变”特性与创建方式二、常用操作:80%场景的“万能工具箱”三、格式化方法

springboot+redis实现订单过期(超时取消)功能的方法详解

《springboot+redis实现订单过期(超时取消)功能的方法详解》在SpringBoot中使用Redis实现订单过期(超时取消)功能,有多种成熟方案,本文为大家整理了几个详细方法,文中的示例代... 目录一、Redis键过期回调方案(推荐)1. 配置Redis监听器2. 监听键过期事件3. Redi

基于SpringBoot实现分布式锁的三种方法

《基于SpringBoot实现分布式锁的三种方法》这篇文章主要为大家详细介绍了基于SpringBoot实现分布式锁的三种方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、基于Redis原生命令实现分布式锁1. 基础版Redis分布式锁2. 可重入锁实现二、使用Redisso

自定义注解SpringBoot防重复提交AOP方法详解

《自定义注解SpringBoot防重复提交AOP方法详解》该文章描述了一个防止重复提交的流程,通过HttpServletRequest对象获取请求信息,生成唯一标识,使用Redis分布式锁判断请求是否... 目录防重复提交流程引入依赖properties配置自定义注解切面Redis工具类controller

Java调用DeepSeek API的8个高频坑与解决方法

《Java调用DeepSeekAPI的8个高频坑与解决方法》现在大模型开发特别火,DeepSeek因为中文理解好、反应快、还便宜,不少Java开发者都用它,本文整理了最常踩的8个坑,希望对... 目录引言一、坑 1:Token 过期未处理,鉴权异常引发服务中断问题本质典型错误代码解决方案:实现 Token

Nginx 访问控制的多种方法

《Nginx访问控制的多种方法》本文系统介绍了Nginx实现Web访问控制的多种方法,包括IP黑白名单、路径/方法/参数控制、HTTP基本认证、防盗链机制、客户端证书校验、限速限流、地理位置控制等基... 目录一、IP 白名单与黑名单1. 允许/拒绝指定IP2. 全局黑名单二、基于路径、方法、参数的访问控制

Python中Request的安装以及简单的使用方法图文教程

《Python中Request的安装以及简单的使用方法图文教程》python里的request库经常被用于进行网络爬虫,想要学习网络爬虫的同学必须得安装request这个第三方库,:本文主要介绍P... 目录1.Requests 安装cmd 窗口安装为pycharm安装在pycharm设置中为项目安装req

nginx跨域访问配置的几种方法实现

《nginx跨域访问配置的几种方法实现》本文详细介绍了Nginx跨域配置方法,包括基本配置、只允许指定域名、携带Cookie的跨域、动态设置允许的Origin、支持不同路径的跨域控制、静态资源跨域以及... 目录一、基本跨域配置二、只允许指定域名跨域三、完整示例四、配置后重载 nginx五、注意事项六、支持