c#更新UI任务

本文关键字:任务 UI 更新 | 更新日期: 2023-09-27 18:01:30

我是C# Task和线程的新手。

我有如下代码:-

public void UpdateSales(object sender, EventArgs args)
{
    Task.Run(() =>
    {
    // Some code Create Collection ...
    // Some code with business logic  ..

    // Below code is to update UI
    // is it safe to update UI like below 
       saleDataGrid.Dispatcher.Invoke((Action) (() =>
                                {
                                    saleDataGrid.ItemsSource = currentCollection;
                                    saleDataGrid.Items.Refresh();
                                })); 
    });
}

我不确定这个代码是否正确。我想在任何情况下都会发生死锁吧?

你能指出我如何从任务中更新UI吗?我不使用async/await,因为UpdateSales是来自第三方库的事件处理程序。

c#更新UI任务

假设在UI线程上调用UpdateSales,一个更简洁的解决方案是:

public async void UpdateSales()
{
  var collection = await Task.Run(() =>
  {
    // Some code Create Collection ...
    // Some code with business logic  ..
    return currentCollection;
  });
  saleDataGrid.ItemsSource = collection;
  saleDataGrid.Items.Refresh();
}

正如我在博客中所描述的,await将在捕获的上下文(在本例中是UI上下文)上自动恢复。我更喜欢使用await的隐式上下文而不是直接使用Dispatcher:代码更短,更易于移植。

你知道,任务。Run将在线程池中执行。

然后您可以使用一个ContinueWith将运行在完成这个任务,如果你选择的一个覆盖允许您指定一个TaskScheduler然后您可以使用TaskScheduler.FromCurrentSynchronizationContext()将使用您输入的同步上下文方法——如果这是一个UI线程(例如在一个事件处理程序的UI事件)的同步上下文将UI线程。

所以你的代码看起来像这样:
Task.Run(() => {
    //...code to create collection etc...
}).ContinueWith(() => {
    saleDataGrid.ItemsSource = currentCollection;
}).TaskScheduler.FromCurrentSynchronizationContext());