繁体   English   中英

使用async / await不保留同步上下文?

[英]Synchronization context not preserved with async/await?

我最近使用async / await模式将一些代码更改为异步。

此代码现在正在创建一个例外:

private async void Refresh(object stateInfo)
{
    await Task.Factory.StartNew(HydrateServerPingDtoList);
    // more code here
}

private void HydrateServerPingDtoList()
{
    // more code here.
    // Exception occurs on this line:
    this._serverPingDtoList.Add(new ServerPingDto() { ApplicationServer = server });
}

例外:

这种类型的CollectionView不支持从与Dispatcher线程不同的线程更改其SourceCollection。

_serverPingDtoList是WPF绑定属性的支持字段。 由于我认为async-await保留了同步上下文,为什么我会收到此错误?

await在其自己的async方法中恢复SynchronizationContext 它不会将它传播到您通过StartNew启动的后台线程。

另外, StartNew不应该用在async代码中; 博客上详细解释了原因 您应该使用Task.Run来执行CPU绑定的代码。

但是,任何UI更新(包括数据绑定属性的更新)都应该在UI线程上完成,而不是在后台任务上完成。 因此,假设您的HydrateServerPingDtoList实际上是CPU绑定的,您可以这样做:

private ServerPingDto HydrateServerPingDtoList()
{
  // more code here.
  return new ServerPingDto() { ApplicationServer = server };
}

private async Task Refresh(object stateInfo)
{
  var serverPingDto = await Task.Run(() => HydrateServerPingDtoList());
  this._serverPingDtoList.Add(serverPingDto);
  // more code here
}

暂无
暂无

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

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