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
是来自第三方库的事件处理程序。
假设在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());