2011-09-26 68 views
0

這就是我的那一刻,但是當我打電話Dispatcher.BeginInvoke(),我的UI死機:在後臺工作實例化對象使UI凍結了

 BackgroundWorker backgroundWorker = new BackgroundWorker(); 
     backgroundWorker.WorkerSupportsCancellation = true; 
     backgroundWorker.WorkerReportsProgress = true; 


     ViewModel.GenerateReport(backgroundWorker, Dispatcher); 

視圖模型:

backgroundWorker.DoWork += delegate(object s, DoWorkEventArgs args) 
     { 
      try 
      { 
       ReportViewModel reportViewModel = new ReportViewModel(SessionContext, Mediator, reportDashboardViewModel.ReportRequest, false); 

       dispatcher.BeginInvoke((Action)(() => 
       { 
        ReportPreviewView reportPreviewView = new ReportPreviewView(reportViewModel); 
        reportPreviewView.ReportName = reportDashboardViewModel.ReportRequest.Report.ReportName; 

        ReportView = reportPreviewView; 
       })); 
      } 
      catch (Exception exception) 
      { 
       backgroundWorker.ReportProgress(0, "There Was an Error generating the report"); 
       backgroundWorker.CancelAsync(); 
       throw; 
      } 
     }; 

     backgroundWorker.RunWorkerAsync(); 

dispatcher.BeginInvoke的第一行會導致我的UI凍結起來。 ReportPreviewView reportPreviewView = new ReportPreviewView(reportViewModel);

注意ReportPreviewView創建報告請求相關視圖。可能是DevexpressC1pivot reports

,只要我取出dispatcher.BeginInvoke,我得到這個錯誤:

The calling thread must be STA, because many UI components require this.

所以我的問題是,我需要做什麼來解決這個問題?

使用BackgroundWorker的全部原因是我的UI始終保持響應。

我是新來multithreading,所以也許我得到了結構中的所有錯誤......

+2

的可能重複[我怎樣才能讓一個後臺工作線程設置爲單線程公寓?](http://stackoverflow.com/questions/4685237/how-can-i-make-a-background-worker-thread -set-to-single-thread-apartment) –

+0

在DoWork中使用BeginInvoke否定Bgw。 'new ReportPreviewView()'在主線程上執行。所以是的,這可以掛你的桂。 –

+0

@亨克霍爾特曼:謝謝你的迴應。你建議我應該做什麼? – Willem

回答

0

這個故事告訴我們,所有的UI元素需要在UI線程上創建!

話雖這麼說,如果UI元素的創建需要很長的時間,用戶界面將凍結。採取所有的舉重,並把它放在TaskBackgroundWorker

那麼你將有一個更加敏感的用戶界面。

2

Disptacher.BeginInvoke啓動您封裝withing的行動ansynchronoulsy的代碼,但Do_Work處理程序也由BackgroundWorker的異步更新,所以你不應該使用它。

的主要問題是,你正試圖從另一個線程訪問UI實例,和窗口禁止的是:只有主線程可以訪問UI元素實例。

正確的方式做到這一點是如果你正在使用Windows窗體使用Control.Invoke。

A deep article about the winforms threading model

+0

感謝Ricky的迴應。我正在使用wpf ...我會用同樣的方法嗎? – Willem

+0

我確實嘗試過'dispatcher.Invoke',但UI仍然凍結... – Willem

+0

@Willem - 您需要在ReportProgress中使用Control.Invoke,因爲它屬於您的應用程序。 –