1

我想从 WPF(c#) 中的多个线程更新我的 DataGrid。我使用 dataGrid.Dispatcher.BeginInvoke() 和 dataGrid.Dispatcher.Invoke() 但它们冻结程序(主线程)。如何在超时的情况下从多个线程更新 dataGrid(因为我使用可能无法访问的 Web 服务)。

4

2 回答 2

3

使用Task异步启动 Web 服务请求。为此,您可能需要将 EAP(基于事件的异步模式)样式转换为 TAP(基于任务的异步模式)样式。这是你如何做到的。

private Task<IEnumerable<YourDataItem>> CallWebServiceAsync()
{
  var tcs = new TaskCompletionSource();
  var service = new YourServiceClient();
  service.SomeOperationCompleted +=
    (sender, args) =>
    {
      if (args.Error == null)
      {
        tcs.SetResult(args.Result);
      }
      else
      {
        tcs.SetException(args.Error);
      }
    };
  service.SomeOperationAsync();
  return tcs.Task;
}

完成后,您可以使用 newasyncawait关键字进行调用并使用延续样式语义等待它返回。它看起来像这样。

private async void Page_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
  IEnumerable<YourDataItem> data = await CallWebServiceAsync();
  YourDataGrid.DataSource = data;
}

这就对了!它没有比这更优雅的了。这将在后台线程上异步执行操作,然后将结果绑定到DataGridUI 线程上。

如果 WCF 服务不可访问,那么它将引发异常并将附加到Task以便它传播到await调用。那时它将被注入到执行中,并且可以在try-catch必要时用 a 包装。

于 2013-11-01T20:11:19.553 回答
1

如果您不需要在线程中完成 DataGrid 编辑,您可以像这样在主线程中运行它们:

this.Invoke((Action)delegate
{
    //Edit the DataGrid however you like in here
});

确保只将需要在主线程中运行的东西放在其中(否则会破坏多线程的目的)。

于 2013-11-01T08:57:11.180 回答