如何等价地使用:
await task.ConfigureAwait(false);
当使用类似于以下方式的continuations时(而不是使用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
的重载传递额外的信息。否则,它会默认在没有执行上下文的情况下运行。
然而,如果我理解错误,请您确认或更正。
TaskScheduler.Default
与提供标志TaskContinuationOptions.HideScheduler
相同。 - MikeTaskScheduler.Default
会在线程池线程上运行委托。TaskContinuationOptions.HideScheduler
将确保TaskScheduler.Current
是TaskScheduler.Default
,即使代码未在默认任务调度程序上运行。 - Stephen ClearyTaskScheduler
传递给ContinueWith
(和StartNew
)。TaskScheduler.Default
属性是线程池,但是ContinueWith
和StartNew
使用的TaskScheduler
实例的默认值不是TaskScheduler.Default
。核心要点是始终传递TaskScheduler
。或者只需使用await
代替ContinueWith
和Run
代替StartNew
,这将使您的代码更易于维护。 - Stephen Cleary