wpf PngBitmap编码器失败

gijlo24d  于 2023-02-16  发布在  其他
关注(0)|答案(1)|浏览(140)

我在一个线程上加载位图,然后在另一个线程上将它们保存到磁盘。
螺纹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属性之外,所有属性都是可访问的。我没有进行任何下载。我从磁盘加载位图,并且在第二个线程完成加载之前它是不可用的--所以这有点神秘,至少对我来说是这样。

cetgtptt

cetgtptt1#

我发现了这个:
WPF BitmapFrame and multiple threads
解决方案似乎是将位图 Package 在CachedBitmap

var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(new CachedBitmap(x, BitmapCreateOptions.None, BitmapCacheOption.OnLoad)));

理想情况下,您可以使用CheckAccess()来确定这一额外步骤是否必要,而不是总是这样做,但CheckAccess()总是出于某种原因返回true。

相关问题