2011-09-27 67 views
0

我在設置主thread的另一個thread上設置Property時出現問題。如何使用另一個線程中的新對象更新屬性?

這是我目前做:

XAML:

<TabControl Name="tab"/> 

代碼背後:

TabItem tabItem = new TabItem(); 

Binding myBinding = new Binding("ReportView") { Source = ViewModel, Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }; 
BindingOperations.SetBinding(tabItem, TabItem.ContentProperty, myBinding); 

tab.Items.Add(tabItem); 

Thread t = new Thread(DoWork); 
t.SetApartmentState(ApartmentState.STA); 
t.Priority = ThreadPriority.Normal; 
t.Start(); 

DoWork的方法:

當我創建ReportPreviewView內身體的Dispatcher.BeginInvoke,我沒有得到exception

public void DoWork(object sender) 
     { 
      //I create the relavant ViewModel 
      ReportViewModel reportViewModel = new ReportViewModel(SessionContext, Mediator, Parent.ReportRequest, false); 

      Dispatcher.BeginInvoke((Action)(() => 
         { 
          //Create the relevant View 
          ReportPreviewView reportPreviewView = new ReportPreviewView(reportViewModel) { ReportName = Parent.ReportRequest.Report.ReportName }; 
          ViewModel.ReportView = reportPreviewView; 
         })); 
     } 

但這是不正確的。它凍結了我的UI thread。創建ReportPreviewView需要很長時間才能退出。

於是我移動ReportPreviewView的創作Dispatcher.BeginInvoke外:

public void DoWork(object sender) 
    { 
     ReportViewModel reportViewModel = new ReportViewModel(SessionContext, Mediator, Parent.ReportRequest, false); 

     ReportPreviewView reportPreviewView = new ReportPreviewView(reportViewModel) { ReportName = Parent.ReportRequest.Report.ReportName }; 

     Dispatcher.BeginInvoke((Action)(() => 
        { 
         reportLoaderViewModel.ReportView = reportPreviewView; 
        })); 
    } 

只要PropertyChanged火我得到以下異常:

調用線程不能訪問此對象,因爲一個不同的線程擁有它

任何想法我可以解決這個問題?

+0

好吧,不知道它有幫助,但是如果你的'ReportPreviewView'拷貝構造函數是輕量級的,你可能只想在'beginInvoke'內創建一個對象的副本並使用它來設置'ReportView'。但我幾乎可以肯定這是行不通的。試試看,這只是一行代碼:) – J0HN

+1

The prequel:http://stackoverflow.com/questions/7553884/instantiating-an-object-in-a-background-worker-causes-the-ui-to - 結冰 –

回答

2

您必須創建 UI調度程序線程上的UI元素。跑不了的。所以當你說

創建ReportPreviewView需要很長時間才能退出。

你有沒有爲什麼?它是否有繪畫,動畫,沉重的風格,非虛擬化面板(如畫布)?它的構造函數是否有一些代碼需要時間才能完成?

如果是這樣,請重新考慮你的UI設計。

在WPF中,UI始終爲凍結了以獲取較大的視圖。即使使用XAMLReader/Writer反序列化視圖,視圖對象的創建和託管也必須在UI線程上進行。

+0

感謝您的迴應。當我說「ReportPreviewView的創建需要很長時間才能退出」時,構造函數有一些代碼需要很長時間......如果你說「重新考慮你的UI設計」,那麼我應該改變什麼呢?我是'multithreading'的新手,所以我在旅途中學習... – Willem

+0

那麼需要花費時間的代碼才能放入'BackgroundWorker'中? –

+0

是的,我可以這麼做......那會是一個可行的解決方案嗎?我的構造函數中所有冗長的操作都必須在它們自己的'thread/task'中? – Willem

相關問題