






















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

TaskCompletionSource<TResult> 是 .NET 中用于手动控制 Task<TResult> 完成时机的工具,常用于将事件驱动或回调模式转换为 async/await 友好形式。TaskCompletionSource有一个属性Task,用于获取当前需要等待的任务。通过TaskCompletionSource,可以设置三种返回结果,如下所示:
对于上述设置方法,在调用时有以下两点需要注意:
在上述TaskCompletionSource设置返回结果的方法中,涉及到当前Task对应的状态,对于一个Task类型的任务,主要有以下几种:
Task的主要属性,如下所示:
接下来,以一个简单的小例子介绍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}");
}
}
当任务正常完成时,通过调用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);
}
}
当任务被取消时,通过调用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();
}
}
当任务执行过程中出现异常时,通过调用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");
});
}
在本示例中,首先有一个开始按钮,用于启动任务:

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

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

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

以上就是《推荐一种手动设置异步线程等待机制的解决方案》的全部内容,旨在抛砖引玉,一起学习,共同进步!
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。