問題描述
為什么我不能在下面的代碼中創建 CroppedBitmap?我遇到了一個例外:
Why I can't create CroppedBitmap in the following code? I got an exception:
調用線程無法訪問此對象,因為另一個線程擁有它.
The calling thread cannot access this object because a different thread owns it.
如果我將代碼更改為
CroppedBitmap cb = new CroppedBitmap(new WriteableBitmap(bf), new Int32Rect(1, 1, 5, 5));
異常消失了嗎?為什么?
the exception is gone? why ?
代碼 1,cb.Freeze()
處的異常:
Code 1, an exception at cb.Freeze()
:
public MainWindow()
{
InitializeComponent();
ThreadPool.QueueUserWorkItem((o) =>
{
//load a large image file
var bf = BitmapFrame.Create(
new Uri("D:\1172735642.jpg"),
BitmapCreateOptions.None,
BitmapCacheOption.None);
bf.Freeze();
Dispatcher.BeginInvoke(
new Action(() =>
{
CroppedBitmap cb = new CroppedBitmap(bf, new Int32Rect(1,1,5,5));
cb.Freeze();
//set Image's source to cb....
}),
DispatcherPriority.ApplicationIdle);
}
);
}
代碼 2,有效:
ThreadPool.QueueUserWorkItem((o) =>
{
var bf = BitmapFrame.Create(
new Uri("D:\1172740755.jpg"),
BitmapCreateOptions.None,
//BitmapCreateOptions.DelayCreation,
BitmapCacheOption.None);
bf.Freeze();
var wb = new WriteableBitmap(bf);
wb.Freeze();
this.Dispatcher.Invoke(
new Action(() =>
{
var r = new Int32Rect(1, 1, 5, 5);
CroppedBitmap cb = new CroppedBitmap(wb, r);
cb.Freeze();
//set Image's source to cb....
Image.Source = cb;
}),
DispatcherPriority.ApplicationIdle);
}
);
代碼 3,無需 WritableBitmap 即可工作:
Code 3, works without WritableBitmap:
ThreadPool.QueueUserWorkItem((o) =>
{
var bf = BitmapFrame.Create(
new Uri("D:\1172735642.jpg"),
BitmapCreateOptions.None,
//BitmapCreateOptions.DelayCreation,
BitmapCacheOption.None);
bf.Freeze();
var bf2 = BitmapFrame.Create(bf);
bf2.Freeze();
this.Dispatcher.Invoke(
new Action(() =>
{
var r = new Int32Rect(1, 1, 5, 5);
BitmapSource cb = new CroppedBitmap(bf2, r);
cb.Freeze();
//set Image's source to cb....
Image.Source = cb;
}),
DispatcherPriority.ApplicationIdle);
}
);
推薦答案
您可以在反射器中查看這些類.cb.Freeze() 中會出現異常.在
You can look through this classes in reflector. Exception will rise in cb.Freeze(). In
CroppedBitmap cb = new CroppedBitmap(bf, new Int32Rect(1,1,5,5));
case 構造函數做了這樣的事情:
case constructor did something like this:
this.this.Source = source;
所以源不是在當前線程中創建的,所以會出現異常.在
So source wasn't created in current thread, and so exception will rise. In
new WriteableBitmap(bf)
案例,構造函數與 bf 對象同步,并且在當前線程中創建了新源,因此不會出現異常.如果您對 In Depth 細節感興趣,您可以隨時使用 Reflector 反射基礎庫 :)
case, constructor synchronize with bf object and new source is created in current thread, so, no exceptions will rise. If you are interested in In Depth details, you can always reflect base libraries with Reflector :)
這篇關于調用線程無法訪問此對象,因為不同的線程擁有它的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!