为什么我在这里看到ConfigureAwait(false)和ConfigureAwait(true)之间没有区别?

时间:2017-01-06 16:55:03

标签: c# .net asynchronous async-await

我正在尝试为async - await上的报告创建概念验证。

我制作了一段代码

using System;
using System.Threading.Tasks;
using System.Threading;

public class Program
{
    static async Task CreateATaskThatPrintsWhichThread()
    {
        Console.WriteLine("Thread on line right before the bottom await = {0}", Thread.CurrentThread.ManagedThreadId);
        await Task.Run(() => 
        {
            Task.Delay(500);
            Console.WriteLine("Thread on line inside bottom task action = {0}", Thread.CurrentThread.ManagedThreadId);                         
        });
        Console.WriteLine("Thread on line right before the bottom await = {0}", Thread.CurrentThread.ManagedThreadId);
    }

    public static void Main()
    {
        Task.Run(async () =>
        {
            Console.WriteLine("Thread on line right before the bottom await = {0}", Thread.CurrentThread.ManagedThreadId);
            Task printStuff = CreateATaskThatPrintsWhichThread();
            printStuff.ConfigureAwait(true);
            await printStuff;
            Console.WriteLine("Thread on line right before the bottom await = {0}", Thread.CurrentThread.ManagedThreadId);
        }).Wait();
    }
}

我在.NET Fiddle上反复运行,结果是零星的:

Thread on line right before the bottom await = 14
Thread on line right before the bottom await = 14
Thread on line inside bottom task action = 28
Thread on line right before the bottom await = 28
Thread on line right before the bottom await = 28


Thread on line right before the bottom await = 28
Thread on line right before the bottom await = 28
Thread on line inside bottom task action = 28
Thread on line right before the bottom await = 28
Thread on line right before the bottom await = 28


Thread on line right before the bottom await = 28
Thread on line right before the bottom await = 28
Thread on line inside bottom task action = 53
Thread on line right before the bottom await = 53
Thread on line right before the bottom await = 28

等等。当我改为`printStuff.ConfigureAwait(false);

Thread on line right before the bottom await = 99
Thread on line right before the bottom await = 99
Thread on line inside bottom task action = 87
Thread on line right before the bottom await = 36
Thread on line right before the bottom await = 99

Thread on line right before the bottom await = 45
Thread on line right before the bottom await = 45
Thread on line inside bottom task action = 36
Thread on line right before the bottom await = 36
Thread on line right before the bottom await = 45

Thread on line right before the bottom await = 25
Thread on line right before the bottom await = 25
Thread on line inside bottom task action = 12
Thread on line right before the bottom await = 12
Thread on line right before the bottom await = 25

有人能告诉我结果“应该”是什么,或者可以帮助我在.NET Fiddle上创建一个更好的例子吗?

(我也很困惑,因为我认为Task.Run里面的线基本上保证在后台线程上执行)

1 个答案:

答案 0 :(得分:1)

评论涵盖了大部分内容,但由于目前还没有答案,我认为您之后的答案是您错误地认为.ConfigureAwait(true)表示在await之后,代码将继续与之前相同的线程。

这在某些情况下是 ,尤其是具有某种形式的消息/调度程序循环的那些。在这些情况下,当预继续代码完成时,捕获的SynchronizationContext用于将请求发送回调度程序 - 当接下来能够 - 接收延续并继续在其线程上执行。循环通常连续快速地旋转,为UI问题提供服务,一旦帖子被注册,它将使用其中一个迭代来执行延续。

控制台应用程序没有这样的循环,也没有SynchronizationContext,因此执行延续的任务将排队到线程池,任何可用的线程都将执行它。你会偶尔获得幸运并最终获得与继续之前相同的帖子,但这只是偶然的。