【问题标题】:Updating DataGrid from multiple threads从多个线程更新 DataGrid
【发布时间】:2013-11-12 10:48:29
【问题描述】:

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

【问题讨论】:

  • 我猜你是在 Dispatcher 调用的方法内进行 Web 服务调用。这当然会冻结 UI。从后台线程调用 Web 服务(在调用Invoke 之前)并仅通过Invoke 将结果传递给 UI 线程。
  • 嗨克莱门斯。可以给我举个例子吗?我是多线程新手。

标签: c# wpf multithreading datagrid timeout


【解决方案1】:

使用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 进行包装。

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • -> 您的答案不包含超时。它也抛出异常。不过谢谢你...
    • @Babak.Abad 真的吗?它抛出什么异常?因为我用过它而且它总是有效的。并且您将超时设置在调用之后,以便它在线程中而不是主线程中运行。
    • 对不起,AlphaDelta。你是说 this.Dispatcher.Invoke(...) 吗?
    • 我看不出有什么例外。但是我看到我的程序被冻结了。 +1 为您提供帮助。如果有其他解决方案请帮助我
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    • 2017-10-07
    • 2011-01-07
    相关资源
    最近更新 更多