gpt4 book ai didi

c# - 使用 ContinueWith 时 ConfigureAwait(false)

转载 作者:太空狗 更新时间:2023-10-29 21:04:01 26 4
gpt4 key购买 nike

什么等同于使用:

await task.ConfigureAwait(false);

当像这样使用延续时(不使用 C# 编译器的 async/await 转换)?

var taskOfString = ScheduleWorkOnThreadPoolAsync();

// I'd like this continuation to not have to
// "flow" the synchronization context but to simply
// execute wherever it can, i.e. I'd like to tell is
// ConfigureAwait(false) for its previous task.
// How do I do that?
taskOfString.ContinueWith(t => { });


public async Task<string> ScheduleWorkOnThreadPoolAsync()
{
return Task.Run(() => return "Foo" );
}

我假设什么都不做,即保持原样等同于调用 ConfigureAwait(false),这也是我在调试代码。它会在任何线程上跳转。

只有当我们想要指定一个调度程序或同步上下文来运行延续时,我们才需要将额外信息传递给接受 TaskScheduler 的重载。否则,它默认在不考虑执行上下文的情况下运行。

但是,如果我错了,我仍然要求确认或更正。

最佳答案

when using continuations like so (without using the C# compiler's async/await transformations)?

你应该几乎总是使用async/await。他们有更安全的默认行为。 ContinueWith 是一个危险的低级 API。

I am assuming that doing nothing, i.e. just leaving it as is is equivalent to calling ConfigureAwait(false)... It is only when we want to specify a scheduler or synchronization context to run the continuation on that we need to pass in extra information to the overload that accepts a TaskScheduler. Otherwise, it is defaulted to run without any regard to the execution context.

没有。这是不正确的,尽管简单的测试不会揭示问题。

正如我在 why you shouldn't use ContinueWith 上的博文中所描述的那样,ContinueWith 的默认 TaskSchedulernot TaskScheduler.Default。它是 TaskScheduler.Current。由于这在每种情况下都会造成混淆,您应该始终TaskScheduler 传递给 ContinueWithStartNew.

如果你想要 await x.ConfigureAwait(false) 行为,你实际上会这样做:

var continuation = x.ContinueWith(callback, CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.DenyChildAttach,
TaskScheduler.Default);

TaskContinuationOptions.ExecuteSynchronously 模拟 synchronous-if-possible behavior of await .如果延续任务是 attached toTaskContinuationOptions.DenyChildAttach 可以防止出现问题(当子任务使用 AttachedToParent 附加到它们时,用于异步的任务会出现令人惊讶的行为)。 TaskScheduler.Default 模拟始终在线程池上下文中执行的 ConfigureAwait(false) 行为。

最后一点,您可能需要对 continuation 做一些事情——至少要观察它是否有异常并以某种方式处理它们。

至此,我推荐await的原因应该很清楚了。在最坏的情况下,您只需要添加一个辅助方法来使用 await 而不是 ContinueWith - await 更易于维护,IMO。

关于c# - 使用 ContinueWith 时 ConfigureAwait(false),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44129886/

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