从多个线程更新DataGrid

时间:2013-11-01 08:36:16

标签: c# wpf multithreading datagrid timeout

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

2 个答案:

答案 0 :(得分: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;
}

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

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

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

如果WCF服务无法访问,那么它将抛出异常并将附加到Task,以便它传播到await调用。此时它将被注入执行中,如果需要,可以用try-catch包装。

答案 1 :(得分:1)

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

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

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