2017-01-06 63 views
-2

我正试图为我在async - await上做的报告创建一个概念验证。为什么我在这里看到ConfigureAwait(false)和ConfigureAwait(true)没有区别?

我由代码

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小提琴运行,结果是散发性的:

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小提琴上创建一个更好的例子吗?

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

+1

您是否发现一半的日志记录使用的字符串与日志中已经使用的其他字符串无法区分?因为我发现令人困惑。 –

+1

为什么你会丢弃由ConfigureAwait返回的任务? –

+3

你应该从编译器得到一个警告来解释这个问题;你忽略了这个警告吗?当你有一些看起来不能正常工作的代码时,请考虑阅读编译器警告;这些警告正试图告诉你为什么代码无法正常工作。 –

回答

1

的意见涵盖了大部分的这一点,但因为没有答案,我认为你之后的答案是你错误地得出结论.ConfigureAwait(true)意味着在await之后,代码将继续与之前相同的线程。

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

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

+1

这是一个很好的链接,解释了为什么控制台应用程序与async/await的行为不同。 http://blog.stephencleary.com/2012/02/async-console-programs.html –

相关问题