C#在任务中更新UI

我是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(); })); }); } 

我不确定这段代码是否正确。 我认为无论如何都会出现死锁?

你能指出我如何从Task更新UI? 我没有使用async/await因为UpdateSales是来自第三方库的事件处理程序。

假设在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 :代码更短,更便携。

如您所知, Task.Run将在线程池线程上执行。

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

所以你的代码看起来像这样:

 Task.Run(() => { ...code to create collection etc... } ) .ContinueWith(() => { saleDataGrid.ItemsSource = currentCollection; } , TaskScheduler.FromCurrentSynchronizationContext() );