簡體   English   中英

WPF進度欄正常工作,但即使使用異步也被阻止在UI線程中

[英]WPF Progress bar working but blocked in UI thread even using async

我正在嘗試在程序中實現不確定的進度條 我是線程技術的新手,但據我所知,這里最好的選擇之一是添加一個異步方法,然后等待“大量”函數執行其結果。 所以我這樣寫:

public void Window_Loaded(object sender, RoutedEventArgs e)
{
    firstLoad();                         
}

private async void firstLoad()
{
    LW.Title = "Loading...";
    LW.Show();

    filterTextBox.Text = defaultSearch;
    await Task.Run(() => InitializeFilter());          
}

private void InitializeFilter()
{

//Asynchronous??? 
Dispatcher.BeginInvoke(new Action(() => {

//... some lines of code that takes some time to run. 

dataGrid.ItemContainerGenerator.StatusChanged += new EventHandler(closeLoadingWindow);

}));

private void closeLoadingWindow(object sender, EventArgs e)
{
    if (LW != null)
    {
        LW.closable = true;
        LW.Close();
    }
}

firstLoad在加載窗口時運行,顯示不確定的LW loadingWindow,並運行InitializeFilter()方法(較重的方法)。 最后,當填充並加載網格時,將觸發一個事件,允許關閉LW窗口並將其關閉(如果我沒有使其無法關閉,那么有趣的用戶可以單擊或使用F4將其關閉,這不太好)。

系統運行正常,並且在時間范圍內一切正常,但是加載欄被凍結,未顯示進度。 相同的LW條在MainWindow中的工作方式相似,但我缺少什么? 提前致謝!

據我所知,這里最好的選擇之一是添加一個異步方法,並等待“重載”函數執行其結果

最好的選擇是使用Task.Run將繁重的處理移至線程池,並使用await檢索其結果。

當前的代碼使用Task.Run移至線程池,然后立即轉過來並使用Dispatcher移回UI線程,然后再執行繁重的處理。 因此,它阻塞了UI線程。

此特定DataGrid顯示的是CollectionView,它不是線程安全的。

正確,您無法從線程池線程更新數據綁定的對象。

最好的解決方案是將繁重的處理與UI更新分開 ,如下所示:

public async void Window_Loaded(object sender, RoutedEventArgs e)
{
  await firstLoadAsync();
}

private List<FilterType> InitializeFilter()
{
  //... some lines of code that takes some time to run. 
}

private async Task firstLoadAsync()
{
  LW.Title = "Loading...";
  LW.Show();

  filterTextBox.Text = defaultSearch;
  var filterData = await Task.Run(() => InitializeFilter()); // Get the plain data on a background thread
  myCollectionView = new CollectionView(filterData); // Update the UI
  if (LW != null)
  {
    LW.closable = true;
    LW.Close();
  }
}

不要使用您的調度程序。 微軟有遠見,可以使用它的魔力(SynchronizationContext)來更新在異步上下文中執行的方法中的UI線程。 這在此處的異步/等待示例中得到證明

而在以前的/其他情況下,您將不得不編組回主(UI)線程以更新UI線程,或者等到完成並從共享狀態的對象中檢索結果。 由於您正在使用async / await,因此最好不要使用調度程序,而應直接更新UI。

暫無
暫無

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

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