- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 ConfigureAwait
,因为我想了解它是如何工作的。
因此,我编写了以下小型控制台应用程序(实际上在 LINQPad 中运行):
void Main()
{
// Use dispatcher to execute the code on STA thread
Dispatcher.CurrentDispatcher.Invoke(() => Run());
}
private async static Task Run()
{
var continueOnCapturedContext1 = true;
var continueOnCapturedContext2 = true;
PrintThreadID();
await Task.Run(() => PrintThreadID()).ConfigureAwait(continueOnCapturedContext1);
PrintThreadID();
await Task.Run(() => PrintThreadID()).ConfigureAwait(continueOnCapturedContext2);
PrintThreadID();
}
private static void PrintThreadID()
{
Console.Write(Thread.CurrentThread.ManagedThreadId.ToString("00") + "\t");
}
我得到了以下输出:
A) 真/真
var continueOnCapturedContext1 = true;
var continueOnCapturedContext2 = true;
1) 11 19 11 07 11
2) 11 09 11 12 11
3) 11 06 11 06 11
预期:调度程序线程 (11) 已被捕获,等待任务在不同或相同的线程池线程上执行。
B) 假/假
var continueOnCapturedContext1 = false;
var continueOnCapturedContext2 = false;
1) 11 23 23 22 22
2) 11 19 19 19 19
3) 11 10 10 10 10
同样预期:未捕获 SynchronizationContext,因此后续可等待和不可等待代码在线程池线程(通常相同)上运行。
C) 假/真
var continueOnCapturedContext1 = false;
var continueOnCapturedContext2 = true;
1) 11 14 14 06 06
2) 11 20 20 20 20
3) 11 17 17 08 08
输出1和3的结果很奇怪。 2. awaitbale 任务是使用选项“在捕获的上下文中继续”执行的,因此我希望它与调用它的代码在同一线程上运行。
似乎 ConfigureAwait(true/false) 对后续的可等待调用没有影响,如果它之前已经调用过,对吧?
最佳答案
The 2. awaitbale task was executed with option "continue on captured context" so I would expect that it runs on the same thread as the code that called it.
假设“context == thread”,但事实并非如此。使用线程池的同步上下文将在线程池中的任何 线程上恢复。现在,如果您不捕获同步上下文,您仍将停留在“线程池中的一个线程”上。
所以是的,如果您已经在一个线程池线程上,那么您是否捕获同步上下文并不重要……继续将仍然在线程池线程上结束。但值得指出的是,多个线程拥有不同的同步上下文是完全合理的,捕获同步上下文将返回到这些线程中的一个,但不一定是同一个线程。 p>
It seems, that
ConfigureAwait(true/false)
has no effect on subsequent awaitable calls if it was already called before, right?
不完全是。如果任务需要使用延续,就会出现这种情况。如果您调用 ConfigureAwait
的第一个任务已经完成,代码将继续同步执行 - 因此此时,第二个 ConfigureAwait
很重要。
例子:
using System;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;
class Test
{
static void Main()
{
var form = new Form();
form.Load += async (sender, args) =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
await Task.FromResult(10).ConfigureAwait(false);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
await Task.Delay(1000).ConfigureAwait(false);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
};
Application.Run(form);
}
}
示例输出:
1
1
5
所以第二个 Console.WriteLine
表明尽管有 ConfigureAwait(false)
,代码仍在同一个线程上运行,因为 Task.FromResult
返回一个已经完成的任务。
关于c# - ConfigureAwait 是否只影响非线程池线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37773854/
我是一名优秀的程序员,十分优秀!