2016-02-26 114 views
0

我這個類,它工作正常避免凍結UI,同時加載

public partial class Home : UserControl 
{ 
    public ObservableCollection<Activity> DataGridRows { get; set; }// = new ObservableCollection<Activity>(); 

    public Home() 
    { 
     InitializeComponent(); 
     DataContext = this; 
     this.Init(); 
    } 

    private void Init() 
    { 
     DataGridRows = new ObservableCollection<Activity>(); 
     refreshGrid(null, null); 
    } 

    private void refreshGrid(object sender, RoutedEventArgs e) 
    { 
     Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => 
     { 
      startRefresh(); //<-- very long operation! 
     })); 
    } 
} 

我的問題是,儘管調用startRefresh()整個程序被凍結,我不能點擊其他按鈕或執行其他操作,直到startRefresh完成。但是我想在後臺運行它。 注意,因爲startRefresh上DataGridRows進行編輯操作和我得到這個例外,我不能與TaskScheduler.FromCurrentSynchronizationContext()方法使用Task對象:

System.NotSupportedException : This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread. 
+1

您可以使用[後臺工作(https://msdn.microsoft.com/en-us/library/cc221403(v = VS.95)的.aspx) –

+0

你需要看看使用BackgroundWorkerThread加載數據多線程。 – ChrisF

+1

有關NotSupportedException異常:http://stackoverflow.com/questions/35359923/visual-basic-net-timer-vs-thread/35363155#35363155(這是在VB .NET中,但相同的概念)。因此,在您StartRefresh方法,則必須調用無論您何時更新的DataGrid –

回答

1

您需要移動大量的數據獲取和處理關閉UI線程。數據準備就緒後,從UI線程更新UI。如果您使用.NET 4.0或更高版本,Task Parallel Library使這種操作更容易。

注意:我做的是startRefresh()既獲取數據和更新UI的假設。如果數據檢索和用戶界面更新處於單獨的方法中,您會對自己更容易。

看到這個答案的更多詳細信息: Avoiding the window (WPF) to freeze while using TPL

+0

在對方回答「不能使用的方法的原因。如果你得到同樣引發NotSupportedException我得到一個異常 – JoulinRouge

+1

,這意味着你正在嘗試從錯誤的線程更新CollectionView。您必須將獲取的長時間運行的數據與更新UI分開。在Task上執行數據提取,然後從UI線程更新UI。 – CHendrix

+0

我使用了背景工作,但你是對的!謝謝! – JoulinRouge

0

我認爲你可以使用awaitable委託命令

public ICommand MyCommand { get; set; } 
    public MainWindow() 
     { 
      InitializeComponent(); 
      this.DataContext = this; 
      MyCommand = new AwaitableDelegateCommand(refreshGrid); 

     } 

    private async Task refreshGrid() 
      { 
       await Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => 
        { 
         Thread.Sleep(10000); 
        })); 
      } 

你可以看看http://jake.ginnivan.net/awaitable-delegatecommand/爲awaitable委託指令

+0

它的工作就像我,同時加載一切都凍結,我不能執行其他操作 – JoulinRouge

+0

你改變你的函數異步?它爲我工作得很好 –