我在一个线程上加载位图,然后在另一个线程上将它们保存到磁盘。
螺纹A上的载荷:
BitmapSource bitmapSource = null;
using (var stream = File.OpenRead(path))
{
bitmapSource = BitmapDecoder
.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad).Frames[0];
bitmapSource.Freeze();
}
// only available to Thread B at this point (i.e after loading is complete).
在线程B上保存:
System.Diagnostics.Debug.Assert(bitmapSource.IsFrozen);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource)); <-- Exception here
...
99%的情况下,这是正常的。但偶尔,我会在“BitmapFrame.Create(bitmapSource)”点遇到异常,调用堆栈如下:
at System.Windows.Threading.Dispatcher.VerifyAccess()
at System.Windows.Media.Imaging.BitmapDecoder.get_IsDownloading()
at System.Windows.Media.Imaging.BitmapFrameDecode.get_InternalMetadata()
at System.Windows.Media.Imaging.BitmapFrame.Create(BitmapSource source)
The calling thread cannot access this object because a different thread owns it.
我真的不知道这是怎么回事。从我的理解,只要你冻结位图源代码,你就可以从另一个线程访问它?我也有一个调试Assert来检查它是否被冻结,它永远不会被触发。如果我在调试器中检查位图源代码对象的所有属性,我会看到以下内容:
除了IsDownloading属性之外,所有属性都是可访问的。我没有进行任何下载。我从磁盘加载位图,并且在第二个线程完成加载之前它是不可用的--所以这有点神秘,至少对我来说是这样。
1条答案
按热度按时间cetgtptt1#
我发现了这个:
WPF BitmapFrame and multiple threads
解决方案似乎是将位图 Package 在
CachedBitmap
中理想情况下,您可以使用
CheckAccess()
来确定这一额外步骤是否必要,而不是总是这样做,但CheckAccess()总是出于某种原因返回true。