2

我最近使用 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 保留了同步上下文,为什么会出现这个错误?

4

1 回答 1

11

awaitSynchronizationContext在自己的async方法中恢复。它不会将其传播到您通过StartNew.

附带说明,StartNew不应在async代码中使用;我在我的博客上详细解释了原因。您应该使用它Task.Run来执行受 CPU 限制的代码。

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

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
}
于 2013-11-01T18:33:11.193 回答