![](/img/trans.png)
[英]Keep UI responsive using Tasks, Handle AggregateException
[英]How to keep the UI responsive while doing background tasks
我實現了一個刷新按鈕,該按鈕讀取數據庫並檢查是否有新條目,並將它們添加到ObservableCollection
。 我有自旋上的價值dependsing刷新圖標IsRefreshing
。 像這樣:
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
IsRefreshing = true;
//Reads database
//ObservableCollection.Add(NewValues)
IsRefreshing = false;
}).Start();
但是運行它給我一個例外:
這種類型的CollectionView不支持從與Dispatcher線程不同的線程對其SourceCollection進行更改。
我顯然會以錯誤的方式進行操作,但是不確定執行后台任務時如何使UI保持響應狀態?
您不能從后台線程修改UI。 所有受支持的.NET版本都允許使用async/await
在后台執行某些操作並返回到UI線程。
ADO.NET,實體框架,Dapper和大多數ORM支持異步執行。 例如,ADO.NET的ExecuteReader
具有等效的ExecuteReaderAsync
方法。 EF的ToList()
具有ToListAsync()
。 Dapper的Query
具有QueryAsync
您應該將事件處理程序更改為以下形式:
private async void btn1_Click(object sender, RoutedEventArgs e)
{
using(var connection = new SqlConnection(_cnString)
{
IsRefreshing = true;
await connection.OpenAsync();
var results=await connection.QueryAsync<Value>(query);
//We're now back in the UI thread
_theCollection.AddRange(results);
IsRefreshing = false;
}
}
調用OpenAsync
或QueryAsync
,.NET將在后台運行查詢並釋放當前(UI)線程。 查詢完成后, await
確保將在原始線程(即UI線程)上恢復執行。
基本上,您必須將此項目添加到集合中,但必須在Dispatcher線程上執行此操作,如下所示:
Application.Current.Dispatcher.Invoke(() => ObservableCollection.Add(NewValues));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.