推荐一种手动设置异步线程等待机制的解决方案

news/2025/12/1 22:42:05/文章来源:https://www.cnblogs.com/hsiang/p/19290918

在实际应用中,异步线程可能需要等待另外的任务完成情况来确定本任务的完成状态。例如图像分析的结果,依赖于图像分析算法对图像的分析,在这种情况下,图像分析并非一种返回结果,根据分析返回的结果来确认图像是好的,还是坏的,进而手动设置异步线程的结果。今天我们以一个简单的小例子,简述在.NET开发中,如何通过TaskCompletionSource来手动设置异步线程的等待结果,仅供学习分享使用,如有不足之处,还请指正。

image

 

TaskCompletionSource概述

 

TaskCompletionSource<TResult> 是 .NET 中用于手动控制 Task<TResult> 完成时机的工具,常用于将事件驱动或回调模式转换为 async/await 友好形式。TaskCompletionSource有一个属性Task,用于获取当前需要等待的任务。通过TaskCompletionSource,可以设置三种返回结果,如下所示:

  • SetCanceled:将TaskCompletionSource.Task 转换为Cancel状态,并在原等待任务中抛出TaskCanceledException异常。
  • SetException:将TaskCompletionSource.Task 转换为Faluted状态,并在原等待任务中抛出对应的Exception异常。
  • SetResult:将TaskCompletionSource.Task 转换为RanToCompletion状态,并设置TResult类型的结果。
  • TrySetCanceled:尝试将TaskCompletionSource.Task 转换为Canceled状态,,并在原等待任务中抛出TaskCanceledException异常。
  • TrySetException:尝试将TaskCompletionSource.Task 转换为Faluted状态,并在原等待任务中抛出对应的Exception异常。
  • TrySetResult:将TaskCompletionSource.Task 转换为RanToCompletion状态,并设置TResult类型的结果。

对于上述设置方法,在调用时有以下两点需要注意:

  • 对于SetCanceled,SetException,SetResult方法,如果当前Task状态已经是RanToCompletion,Faulted,Canceled,则在设置时抛出InvalidOperationException。
  • 对于TrySetCanceled,TrySetException,TrySetResult,如果Task已经是RanToCompletion,Faulted,Canceled,则返回false,否则返回true。

在上述TaskCompletionSource设置返回结果的方法中,涉及到当前Task对应的状态,对于一个Task类型的任务,主要有以下几种:

  • Created‌:任务已创建但尚未启动。
  • ‌WaitingForActivation‌:任务已创建但未被激活(例如通过Start方法)。
  • ‌WaitingToRun‌:任务已激活但尚未开始执行。
  • ‌Running‌:任务正在执行中。
  • ‌WaitingForChildrenToComplete‌:任务本身已完成,但其子任务仍在运行(仅适用于父任务)。
  • ‌RanToCompletion‌:任务已成功完成。
  • ‌Canceled‌:任务因取消操作终止。
  • ‌Faulted‌:任务因未处理异常终止。 ‌

Task的主要属性,如下所示:

  • ‌Task.Status‌:获取当前任务的TaskStatus值。 ‌
  • ‌IsCanceled‌:检查任务是否因取消完成。 ‌
  • ‌IsFaulted‌:检查任务是否因异常完成。 
  • ‌IsCompleted‌:检查任务是否已完成(无论成功、取消或异常)。 ‌

 

TaskCompletionSource用法

 

接下来,以一个简单的小例子介绍TaskCompletionSource的使用方法,首先创建的一个任务异步执行Running方法,并在Running方法中等待TaskCompletionSource.Task的完成和获取结果,如下所示:

private Task task;private TaskCompletionSource<bool> tcs;public MainForm()
{InitializeComponent();
}private void btnStart_Click(object sender, EventArgs e)
{tcs = new TaskCompletionSource<bool>();task = Task.Run(async () =>{await Running(this.tcs);});}private async Task Running(TaskCompletionSource<bool> tcs)
{try{this.OutputInfo("当前开始工作中");bool result = await tcs.Task;this.OutputInfo($"当前已完成工作,IsComplete={tcs.Task.IsCompleted},结果为{result}");}catch (TaskCanceledException ex){this.OutputInfo($"当前已取消工作,IsCancelled = {tcs.Task.IsCanceled}");this.OutputInfo($"异常信息如下:");this.OutputInfo($"{ex.Message}");}catch (Exception ex2){this.OutputInfo($"当前工作出现了异常,IsFaulted={tcs.Task.IsFaulted}");this.OutputInfo($"异常信息如下:");this.OutputInfo($"{ex2.Message}");}
}

 

设置Result

 

当任务正常完成时,通过调用SetResult或TrySetResult方法,将任务状态转换为RanToCompletion,Running方法中的任务正常完成。此方法接收一个参数,用于设置Task返回的结果,类型由定义TaskCompletionSource时指定的泛型确定,如下所示:

private void btnEnd_Click(object sender, EventArgs e)
{if (this.tcs != null && this.tcs.Task.Status==TaskStatus.WaitingForActivation){this.tcs.SetResult(true);}
}

 

设置Canceled

 

当任务被取消时,通过调用SetCanceled或TrySetCanceled方法,将任务状态转换为Canceled,此时Running方法中的任务将抛出TaskCanceledException,如下所示:

private void btnCancel_Click(object sender, EventArgs e)
{if (this.tcs != null && this.tcs.Task.Status == TaskStatus.WaitingForActivation){this.tcs.SetCanceled();}
}

 

设置Exception

 

当任务执行过程中出现异常时,通过调用SetException或TrySetException方法,将任务状态转换为Faluted,此时Running方法总的任务将抛出对应设置的Exception,如下所示:

private void btnExce_Click(object sender, EventArgs e)
{if (this.tcs != null && this.tcs.Task.Status == TaskStatus.WaitingForActivation){this.tcs.SetException(new Exception("Okcoder异常出现"));}
}

在上述方法中,引用的Output方法为自定义方法,用于将信息输出到文本框中,如下所示:

private void OutputInfo(string msg)
{this.Invoke(() =>{this.txtInfo.AppendText($"{msg}\r\n");});
}

 

示例演示

 

在本示例中,首先有一个开始按钮,用于启动任务:

image

结束按钮,用于设置正常的任务结束,并返回结果

image

一个取消按钮,用于取消任务

image

一个异常按钮,用于设置运行过程中出现的异常信息

image

以上就是《推荐一种手动设置异步线程等待机制的解决方案》的全部内容,旨在抛砖引玉,一起学习,共同进步!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/983497.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LangChain4j实战-嵌入(向量)存储Embedding(Vector)Stores

LangChain4j实战-嵌入(向量)存储Embedding(Vector)Stores 向量相关的概念 向量的基本定义数学定义:向量是一个有序的数字列表,通常表示为[v1,v2,...,vn],其中每个数字称为分量,对应一个维度。向量既可以看作空间中…

12.1每日总结

今天的主要课程有案例分析、软件设计、大数据、物联网,案例分析课上提前做了期末考试的题型,软件设计和大数据的实验也在继续完善,加油

Java/PHP源码解析:一站式上门维修服务系统的全栈完成

Java/PHP源码解析:一站式上门维修服务系统的全栈完成pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&qu…

实用指南:在智能制造语境下理解ISA-95、IIoT和UNS

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

251201本年进入最后一个月

今天找到一点学习的感觉,就是要专注投入,由此可见,专注力是很珍贵的。

20251201

接下来一个月得自己实操springweb,不能一直用ai辅助了

12月1号

今天进行了统一建模和数据结构的学习。 然后进行了java的练习。

AI浏览器Dia的华丽转身:从安全漏洞到垂直标签的回归

本文作者分享了其对The Browser Company旗下浏览器Arc与Dia的使用体验。文章详述了Dia早期版本过度依赖AI功能带来的安全风险(如提示注入攻击),以及后续更新如何回归Arc的成功核心:垂直标签栏、键盘快捷操作等提升…

2025-12-01

CF Problem - 1455D - Codeforces 贪心,从小到大遍历 因为a[i]>x才能交换 所以把大的换小,使其满足单调不递减 #include <bits/stdc++.h> using namespace std; #define LL long long const LL mod = 99824…

PyTorch入门:一步步训练你的首个深度学习模型

本文是一份详尽的PyTorch入门实践教程,指导读者如何使用PyTorch框架构建并训练一个多层感知机(MLP)模型。内容涵盖环境配置、数据加载与预处理、模型定义、训练与验证循环编写等核心步骤,并通过CIFAR10图像分类任务…

2025最新锂电池品牌/电动车锂电池厂家推荐!电动车储能电池生产厂家权威榜单,恒续能源等TOP5企业实力解析

引言 后疫情时代新能源产业迎来爆发式增长,锂电池作为核心动力源,行业竞争呈现技术迭代加速、产品差异化加剧的新格局。据中国化学与物理电源行业协会数据,2024年全球动力电池装机量达652GWh,同比增长37%,储能电池…

2025最新锂电池品牌推荐!电动车与储能电池优质厂家权威榜单发布,技术实力铸就行业标杆

随着新能源产业的蓬勃发展,锂电池作为核心能源载体,其性能与品质直接决定下游应用的竞争力。本榜单基于技术创新、生产规模、客户口碑三大维度,结合行业权威数据与市场反馈,为您解析2025年五大锂电池品牌综合实力,…

深入解析:【SpringBoot】32 核心功能 - 单元测试 - JUnit5 单元测试中的嵌套测试与参数化测试详解

深入解析:【SpringBoot】32 核心功能 - 单元测试 - JUnit5 单元测试中的嵌套测试与参数化测试详解2025-12-01 22:16 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !…

MYSQL - explain

MYSQL - explain 准备数据 drop table orders; drop table products; drop table users;CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, email VARCHAR(100) NOT NULL, passwor…

【UEFI基础】Protocol介绍

简要说明 Protocol是UEFI中的一个重要概念(事实上《UEFI SPEC》中有超过70%的内容都是在讲Protocol),下面简单说明下:首先,非常重要的一点,Protocol不是什么特殊的东西,它就是一个结构体,比如说下面是一个用于…

清障车口碑排行:2025年最受推荐品牌TOP5,清障车/二手清障车蓝牌/重载清障车/清障车带吊/清障车企业找哪家

行业权威榜单揭晓,五大品牌引领清障车市场新格局 随着我国道路交通网络的不断完善和汽车保有量的持续增长,清障车作为道路救援领域的重要装备,其市场需求呈现出稳步上升态势。本文基于市场调研数据、用户反馈及产品…

2025年目前评价高的智能货架厂家口碑推荐,钢制货架/重载货架/仓库货架/模具架/精益管料架/背网货架/智能货架厂家榜单推荐

智能仓储升级浪潮下的优质供应商盘点 随着智能制造与物流自动化需求的持续增长,智能货架作为仓储系统的核心装备,其市场关注度显著提升。本文基于企业规模、技术实力、客户案例及市场反馈等多维度数据,对当前国内智…

Flink - PyFlink

Flink - PyFlinkI have installed Apache Flink and run start-cluster.sh. How to use it with PyFlink? ChatGPT said:Perfect! Since you already have Apache Flink installed and the cluster is running, you c…

2025年GEO公司推荐榜单,GEO服务/GEO优化AI搜索/GEO优化AI工具排名/GEO老牌厂家排行

行业洞察与榜单背景 随着人工智能技术的快速发展,GEO优化服务正成为企业品牌传播的重要战略方向。据行业数据显示,2024年已有超过65%的企业将AI内容优化纳入营销预算,预计2025年这一比例将提升至80%。本文基于市场调…

STM32F103直流有刷电机速度闭环控制

在《基于直流有刷电机的速度闭环控制以及matlab仿真》我们介绍了速度闭环控制的实现,其采用的是PID控制算法,本节我们就基于STM32F103来实现直流电机的增量式PID速度闭环控制。 一、软件实现 我们需要将PID控制器应用…