簡體   English   中英

如何在執行后台任務時保持UI響應

[英]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;
    }
}

調用OpenAsyncQueryAsync ,.NET將在后台運行查詢並釋放當前(UI)線程。 查詢完成后, await確保將在原始線程(即UI線程)上恢復執行。

基本上,您必須將此項目添加到集合中,但必須在Dispatcher線程上執行此操作,如下所示:

Application.Current.Dispatcher.Invoke(() => ObservableCollection.Add(NewValues));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM