gpt4 book ai didi

C# 异步 CTP - 如何在不抛出 TaskCanceledException 的情况下将异步任务标记为已取消?

转载 作者:太空狗 更新时间:2023-10-29 21:46:45 25 4
gpt4 key购买 nike

我有一个简短的异步任务,它在启动后经常需要取消。 “任务”类有一个 IsCanceled 指示器,我认为可以方便地使用它来指示异步任务在没有运行完成的情况下被取消,但据我所知,将异步任务标记为已取消的唯一方法是在异步函数中抛出 TaskCanceledException。例行公事地抛出一个异常,以表明一种无异常发生的情况,违背了我理解应该使用异常的方式。有谁知道更好的方法来指示异步任务在预期经常发生时被取消?

我的下一个最佳选择是返回一个具有自己的 IsCanceled 属性的结构:

(为简洁起见,我在这里忽略了一些良好的编码和样式实践)

class MightBeCanceled<T>
{
public readonly T Value;
public readonly bool IsCanceled;

public MightBeCanceled(T value) { Value = value; IsCanceled = false; }
public static MightBeCanceled<T> Canceled = new MightBeCanceled<T>(default(T), true);
private MightBeCanceled(T value, bool isCanceled) { Value = value; IsCanceled = isCanceled; }
}

...

static async Task<MightBeCanceled<int>> Foo()
{
if (someCancellationCondition)
return MightBeCanceled<int>.Canceled;
else
return new MightBeCanceled<int>(42);
}

static async void Bar()
{
var mightBeCanceled = await Foo();

if (mightBeCanceled.IsCanceled)
; // Take canceled action
else
; // Take normal action
}

但这似乎是多余的并且更难使用。更不用说它引入了一致性问题,因为会有两个 IsCanceled(一个在 Task 中,一个在 MightBeCanceled 中)。

最佳答案

通常 Cancellation 的目的是让异步操作的调用者告诉操作它应该停止处理。为此,你传递一个 CancellationToken进入异步方法。这就是为什么等待设置 IsCancelled 的任务抛出自身。这意味着对外部激发的 Action 发出特殊信号。任务的取消不应用于控制流,而只是为异步操作提供在等待方表示不再需要结果时提前完成的选项。

如果您的异步操作在内部被取消,那么您已经重载了这个概念,我会说反射(reflect)取消中的差异是值得的,并且应该是结果容器上的一个属性,类似于您提出的方式。但不是称它为 MightBeCancelled<T> , 也许像 InternallyCancellableResult<T> , 以反射(reflect)对消概念的差异。

关于C# 异步 CTP - 如何在不抛出 TaskCanceledException 的情况下将异步任务标记为已取消?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7032476/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com