簡體   English   中英

在線程中使用Dispatcher.BeginInvoke時出現奇怪的線程異常

[英]Weird Thread exception when using Dispatcher.BeginInvoke in a thread

我正在線程中運行一個非常耗時的方法,它的作用之一是,如果沒有可用的圖像,它將設置名為Background的背景的網格為純色。 該代碼段的外觀如下:

SolidColorBrush scb = new SolidColorBrush();
scb.Color = Color.FromRgb(21, 21, 21);
Dispatcher.BeginInvoke(new Action(() => Background.Background = scb)); 

但是我總是在這個地方出錯,說: "Cannot use a DependencyObject that belongs to a different thread than its parent Freezable"

有人知道為什么會這樣嗎? 調度員應該解決這個問題,對嗎?

這是我如何調用該方法的方式(如果需要)

Thread BGthread = new Thread(HandleBackgrounds);
BGthread.Start();

SolidColorBrush是一個依賴項對象-您正在非UI線程中創建它,然后嘗試在UI線程中使用它。 嘗試以下方法:

Action action = () =>
{
    SolidColorBrush scb = new SolidColorBrush(Color.FromRgb(21, 21, 21));
    Background.Background = scb;
};
Dispatcher.BeginInvoke(action);

或當然只是一個陳述:

Dispatcher.BeginInvoke((Action (() =>
    Background.Background = new SolidColorBrush(Color.FromRgb(21, 21, 21)))));

無論哪種方式,您都將在傳遞給調度程序的操作中創建SolidColorBrush

BrushDispatcherObject ,因此它具有線程相似性-它屬於創建它的線程,通常只能由它使用。

但是,WPF有一個調度程序對象的子類,稱為Freezable ,您可以通過將其設為只讀來刪除線程關聯。 畫筆是可凍結的,因此您可以在線程上創建一個並將其傳遞給另一個:

var scb = new SolidColorBrush(Color.FromRgb(21, 21, 21));
scb.Freeze();
Dispatcher.BeginInvoke(new Action(() => Background.Background = scb)); 

如果要在未在UI線程上創建的視圖模型中創建畫筆,這將很有用。 另一個常見用例是在不同線程上解碼圖像,這可以提高性能( ImageSource也是可凍結的)。

凍結可凍結對象也被視為性能優化 ,因此請盡可能使用它。

暫無
暫無

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

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