0

据此_

如果 BackgroundWorker 从其 DoWork 处理程序启动另一个 BackgroundWorker,则嵌套的 BackgroundWorker 不会捕获 UI SynchronizationContext

在此处输入图像描述

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

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 线程?

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

请帮助我消除混乱。

4

1 回答 1

4

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

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

于 2013-09-13T01:19:31.730 回答