2012-06-27 25 views
3

我宣佈一個字段對象:線程不能訪問

WriteableBitmap colorBitmap; 

然後,我創建了一個簡單的線程它做一些事情:

private void doSomething() 
{ 
    // ... bla bla bla 
    colorBitmap = new WriteableBitmap(/* parameters */); 
    myImage.Source = colorBitmap; // error here:S 
} 

在Windows_Loaded事件中,我宣佈,開始一個新的線程:

private void window_Loaded(object sender, RoutedEventArgs e) 
{ 
    Thread th = new Thread(new ThreadStart(doSomething)); 
    th.Start(); 
} 

問題是我無法更改myImage的源代碼。我有這樣的錯誤:

InvalidOperationException異常是未處理 ,因爲不同的線程擁有它調用線程不能訪問該對象。

我試圖用Dispatcher.Invoke,但它並沒有幫助...

Application.Current.Dispatcher.Invoke((Action)delegate 
{ 
    myImage.Source = colorBitmap; 
}); 

我正在尋找一些答案,但從來沒有發現的情況下完全按照我的。任何1可以幫助我理解如何解決這樣的問題(我最近有同樣的問題,但我無法調用該方法,因爲其他線程擁有它)。

+2

好了,從我的頭頂,我想這是WPF或Silverlight?如果我記得正確(我很少這麼做!),你不能在後臺線程上實例化一個新的'WriteableBitmap'(出於某種愚蠢的原因)。不知道爲什麼它調度到主線程後不起作用。也許嘗試'myImage.Dispatcher.Invoke'而不是'Application.Current.Displatcher.Invoke'? –

+0

例如,請參閱http://stackoverflow.com/questions/1855308/asynchronous-operations-on-writeablebitmap。這是一個特殊情況 - 如果你看到文檔http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.aspx,那麼解釋是'當更新發送到渲染線程渲染線程將已更改的矩形從後臺緩衝區複製到前臺緩衝區。渲染系統控制此交換以避免死鎖和重繪工件,例如「撕裂」。 – dash

+0

myImage.Dispatcher.Invoke - 同樣的錯誤 – Nickon

回答

8

有兩個問題與您的代碼:

  1. 您不能從另一個線程比誰創造了它的一個不同的訪問WriteableBitmap。如果你想這樣做,你需要通過首先調用WriteableBitmap.Freeze()來凍結你的位圖

  2. 你不能在不是調度程序線程的線程中訪問myImage.Source。這種方法可以讓你無論你在你的線程要創建和更新您的位圖

    private void doSomething() 
    { 
        // ... bla bla bla 
        colorBitmap = new WriteableBitmap(/* parameters */); 
        colorBitmap.Freeze(); 
        Application.Current.Dispatcher.Invoke((Action)delegate 
        { 
         myImage.Source = colorBitmap; 
        }); 
    } 
    

    編輯 注:

這應該可以解決雙方的這兩個問題。一旦位圖被凍結,它就不能再被修改,在這種情況下,你應該把它丟棄並創建一個新的。

在一個側面說明,如果您不希望阻止您的線程更新myImage.Source使用BeginInvoke代替Invoke

+0

好吧,它的工作。現在沒有錯誤。但是如何在凍結時編輯colorBitmap?如何解凍它? – Nickon

+0

很高興它的工作,至於你的問題,請參閱我的編輯 – GETah

+0

+1以獲得良好的分析 – MBen