【问题标题】:SynchronizationContext default behavior in TAP (Task Async Pattern)TAP 中的 SynchronizationContext 默认行为(任务异步模式)
【发布时间】:2013-09-13 00:53:53
【问题描述】:

根据this

如果 BackgroundWorker 从它的 DoWork 处理程序,则嵌套的 BackgroundWorker 不会捕获 UI SynchronizationContext

但是对于 .NET 4.0 尤其是 4.5 以后的版本,我从 here 看到了很多类似这样的示例代码:

public partial class Form1 : Form
{
   public Form1()
   {
      InitializeComponent();

      Shown += async ( s, e ) => { txtResult.Text = await DownloadAsync() + "Done!"; };
   }

   async Task<string> DownloadAsync()
   {
      using ( var wc = new WebClient() )
      {
         var progress = new Progress<DownloadStringTaskAsyncExProgress>();

         progress.ProgressChanged += ( s, e ) =>
            {
               progressBar.Value = e.ProgressPercentage;
               txtResult.Text += e.Text;
            };

         return await wc.DownloadStringTaskAsyncEx(
            @"http://ancillaryasync.nickbutler.net/Murphy.ashx", progress );
      }
   }
}

所以看起来您可以使用任务嵌套异步调用,并且 SynchronizationContext 将向下浮动嵌套调用。这是正确的吗?

如果是这样,有人可以向我解释一下 TAP 如何在非常高的级别上做到这一点。

如果不是,我需要做什么来确保我的嵌套调用可以发布到 UI 线程?

或者可能是我对原文章的理解完全错误?默认情况下,新任务的创建是否会选择当前的同步上下文?如果是这样,除非你明确地给它一个新的同步上下文,否则它怎么能在原始同步上下文之外的任何东西上运行?

请帮我解惑。

【问题讨论】:

    标签: c# asynchronous task-parallel-library desktop-application synchronizationcontext


    【解决方案1】:

    首先,您引用的文章是在谈论BackgroundWorker 而不是asyncBackgroundWorker 在 .NET 4.5 中的工作方式仍然相同,并且仍然存在嵌套调用的限制。

    有关async 如何与SynchronizationContext 一起使用的说明,您可以查看该文章的末尾或阅读我的intro on async。简而言之,当遇到await 时,默认情况下它将捕获当前的SynchronizationContext(或者如果是null,则为当前的TaskScheduler),并使用它来安排继续。

    【讨论】:

      猜你喜欢
      • 2014-06-19
      • 1970-01-01
      • 1970-01-01
      • 2019-11-24
      • 1970-01-01
      • 2017-01-25
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      相关资源
      最近更新 更多