繁体   English   中英

TAP中的SynchronizationContext默认行为(任务异步模式)

[英]SynchronizationContext default behavior in TAP (Task Async Pattern)

根据这个

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

还是我对原始文章的理解是完全错误的? 默认情况下,创建新任务会获取当前同步上下文吗? 如果是这样,除非您明确为其提供新的同步上下文,否则它将如何在除原始同步上下文之外的任何其他对象上运行?

请帮助我消除混乱。

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

有关async如何与SynchronizationContext工作的描述,可以查看该文章的末尾,也可以阅读我关于async介绍 简而言之,当遇到await时,默认情况下它将捕获当前的SynchronizationContext (或者如果它为null ,则返回当前TaskScheduler ),并使用它来计划继续。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM