C# 异步方法、取消和任务状态

C# 异步方法、取消和任务状态,c#,.net,async-await,cancellation,C#,.net,Async Await,Cancellation,给定一个方法签名,如 Taks<int> ComputeAsync(..., CancellationToken cancellationToken) 输出: RanToCompletion - RanToCompletion Faulted - Faulted Canceled - Canceled Faulted - Canceled 然而,我似乎找不到关于上述行为的任何文档或其他信息。跨框架版本可以依赖它吗 如果答案是肯定的,那么cancellationToken.Thro

给定一个方法签名,如

Taks<int> ComputeAsync(..., CancellationToken cancellationToken)
输出:

RanToCompletion - RanToCompletion
Faulted - Faulted
Canceled - Canceled
Faulted - Canceled
然而,我似乎找不到关于上述行为的任何文档或其他信息。跨框架版本可以依赖它吗

如果答案是肯定的,那么
cancellationToken.ThrowIfCancellationRequested()
将做正确的事情,但不捕获
OperationCanceledException
s(可能来自
wait
ed任务)可以设置任务
已取消
,尽管
!cancellationToken.IsCancellationRequested
。因此,为了获得可预测和正确的结果,我们是否需要将每个可取消的异步方法包装到一个try/catch中,以确保不会抛出OCE,除非它位于正确的
CancellationToken
,还是有更优雅的方法


如果答案是否定的,那么我们是否必须退回到
TaskCompletionSource
内容?

从您的示例中可以看出,您使用cancellationToken的意图并不明确。因此,我将不得不从我对它的使用说起。我们使用Windows服务,需要知道是否使用了OnStop事件。TokenSource对象具有Cancel方法,用于向任务发出需要停止操作的信号。令牌布尔值表示请求取消。通过抛出OperationCancelled-您可以捕获该值并优雅地处理它。这一切都是以控制任务同步的名义进行的。如果您这样做,您的场景在某些方面也会有相同的需求。 补充说明2018年7月16日:

你在问题中喊出一个签名(任务上拼写正确)

这与你的问题完全不符。 下面是关于FromResult的作用的stackoverflow答案

在运行代码看来,它已被取消。这就是为什么它抛出了一个
操作canceledException
。如果您不同意此评估,则更多的是您与此代码的开发人员之间的人员讨论,而不是在呼叫站点解决的技术问题。也就是说,如果您担心此场景,为什么您不担心一些实现,例如,它们实际上成功地完成了工作,然后抛出一些其他异常,导致出现
故障
状态,而不是
RanToCompletion
,这是它们应该报告的。实际上,我担心两件事:1。如果由于令牌被取消(通常通过
cancellationToken.ThrowIfCancellationRequested()
),实现异步方法抛出OCE,返回的任务是否保证处于
cancelled
状态?测试代码说是的,但似乎是一个未记录的特性。2.如果从async方法中调用的某个代码在其他某个
CancellationToken
上抛出OCE,则返回的任务将以
CancellationToken
结束,尽管传递给该方法的令牌没有请求这样做。感谢您的回答。但是,这并没有回答我的问题,这是关于如何将所需的行为实现为
异步
方法,而不是返回
TaskCompletionSource.Task
RanToCompletion - RanToCompletion
Faulted - Faulted
Canceled - Canceled
Faulted - Canceled
Task<int> ComputeAsync(..., CancellationToken cancellationToken)
Summary:
    //     Creates a System.Threading.Tasks.Task`1 that's completed 
successfully with the
    //     specified result.