在哪种情况下TaskCompletionSource.SetResult()会同步运行延续? [英] In which case does TaskCompletionSource.SetResult() run the continuation synchronously?

查看:345
本文介绍了在哪种情况下TaskCompletionSource.SetResult()会同步运行延续?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最初,我认为所有延续都在线程池上执行(给定默认的同步上下文).但是,当我使用TaskCompletionSource时,情况似乎并非如此.

Initially I thought that all continuations are executed on the threadpool (given a default synchronization context). This however doesn't seem to be the case when I use a TaskCompletionSource.

我的代码如下:

Task<int> Foo() {
  _tcs = new TaskCompletionSource<int>();
  return _tcs.Task;
}

async void Bar() {
  Console.WriteLine(Thread.Current.ManagedThreadId);
  Console.WriteLine($"{Thread.Current.ManagedThreadId} - {await Foo()}");
}

Bar在特定线程上被调用,并且TaskCompletionSource保持未设置状态一段时间,这意味着返回的任务IsComplete = false.然后过了一段时间,同一线程将继续调用_tcs.SetResult(x),据我所知,应该在线程池上运行延续.

Bar gets called on a specific thread and the TaskCompletionSource stays unset for some time, meaning the returned tasks IsComplete = false. Then after some time, the same thread would proceed to call _tcs.SetResult(x), which by my understanding should run the continuation on the threadpool.

但是我在应用程序中观察到的是,运行延续的线程实际上仍然是同一个线程,就好像在调用SetResult时同步调用了延续一样.

But what I observed in my application is that the thread running the continuation is in fact still the same thread, as if the continuation was invoked synchronously right as SetResult is called.

我什至尝试在SetResult上设置一个断点并跨过它(并在延续中有一个断点),这实际上又继续同步调用延续.

I even tried setting a breakpoint on the SetResult and stepping over it (and having a breakpoint in the continuation), which in turn actually goes on to call the continuation synchronously.

SetResult()何时确切立即同步调用延续?

When exactly does SetResult() immediately call the continuation synchronously?

推荐答案

SetResult 通常通常从TCS同步运行延续.最主要的例外是,如果您在创建TCS(.NET 4.6中的新增功能)时明确地传递TaskContinuationOptions.RunContinuationsAsynchronously标志.异步运行事物的另一种情况是,它认为当前线程注定要失败.

SetResult usually runs continuations from TCS synchronously. There main exception to this is if you explicitly pass in the TaskContinuationOptions.RunContinuationsAsynchronously flag when creating the TCS (new in .NET 4.6). The other scenario when it runs things asynchronously is if it thinks the current thread is doomed.

这非常重要,因为如果不注意,最终可能会导致调用代码控制一个本来打算做其他工作的线程(例如:处理套接字IO).

This is quite important, because if you're not careful you can end up having calling code take control of a thread that was meant to be doing other work (like: dealing with socket IO).

这篇关于在哪种情况下TaskCompletionSource.SetResult()会同步运行延续?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆