当前位置: 首页 > news >正文

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

在实际应用中,异步线程可能需要等待另外的任务完成情况来确定本任务的完成状态。例如图像分析的结果,依赖于图像分析算法对图像的分析,在这种情况下,图像分析并非一种返回结果,根据分析返回的结果来确认图像是好的,还是坏的,进而手动设置异步线程的结果。今天我们以一个简单的小例子,简述在.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.jsqmd.com/news/57522/

相关文章:

  • 12.1每日总结
  • Java/PHP源码解析:一站式上门维修服务系统的全栈完成
  • 251201本年进入最后一个月
  • 20251201
  • 12月1号
  • 2025最新锂电池品牌/电动车锂电池厂家推荐!电动车储能电池生产厂家权威榜单,恒续能源等TOP5企业实力解析
  • 2025最新锂电池品牌推荐!电动车与储能电池优质厂家权威榜单发布,技术实力铸就行业标杆
  • 【UEFI基础】Protocol介绍
  • 清障车口碑排行:2025年最受推荐品牌TOP5,清障车/二手清障车蓝牌/重载清障车/清障车带吊/清障车企业找哪家
  • 2025年目前评价高的智能货架厂家口碑推荐,钢制货架/重载货架/仓库货架/模具架/精益管料架/背网货架/智能货架厂家榜单推荐
  • Flink - PyFlink
  • 2025年GEO公司推荐榜单,GEO服务/GEO优化AI搜索/GEO优化AI工具排名/GEO老牌厂家排行
  • STM32F103直流有刷电机速度闭环控制
  • 英语_阅读_City Park Facilities Survey_待读
  • 2025年石笼网优质供应商排名,这5家好评不断,双隔板石笼网/抗冲击抗腐蚀石笼网/锌铝合金石笼网/镀锌低碳钢丝石笼网源头厂家选哪家
  • 2025成都抖音代运营机构口碑排行榜单发布,网络营销/小红书代运营/快手代运营/GEO优化/抖音代运营/抖音代运营公司找哪家
  • 格宾石笼网2025年生产公司排名,哪家更值得选择?镀锌低碳钢丝石笼网/抗冲击抗腐蚀石笼网/格宾石笼网实力厂家选哪家
  • 2025.12.1
  • Keep dreaming, remain loving. / NOIP2025 游记
  • 2025十大私域电商核心工具:小鹅通领跑全链路生态,赋能增长新范式
  • 第四十三天
  • 哪家无人机培训机构可以考证?国内正规机构推荐
  • 明日也要加油
  • 完整教程:【图像处理】jpeg 格式详解
  • 12.1 日志
  • 无人机培训学校有哪些?国内优质机构推荐
  • 我在CSDN学MYSQL之----数据库基本概念和基本知识(下) - 教程
  • 基于Springboot的旧物公益捐赠管理系统3726v22v(程序、源码、数据库、调试部署方案及开发环境)架构界面展示及获取方式置于文档末尾,可供参考。
  • 2025年最新防雨棚供应商排行榜,联系电话一键获取,一体化监控杆/方舟控制台/八角监控杆/交通监控杆/防雨棚供应厂家联系电话
  • 3.5 分页系统中的设计问题 Design Issues For Paging Systems