在后台线程上创建位图会暂停渲染线程
本文关键字:线程 暂停 创建 后台 位图 | 更新日期: 2023-09-27 17:57:26
一点背景:我正在为声纳记录回放的显示设置动画。声纳记录文件很大(通常为100-600MB),因此根据需要加载段。它的核心是我们预先索引声纳文件,然后根据需要使用内存映射文件加载数据块。然后,数据被用来创建位图——非常简单,因为数据由字节组成,我们只需使用8位调色板将这些数据映射到颜色。
出于性能原因,我们在后台进行所有加载,并在其自己的图形中将每个片段渲染为视觉效果。这很好,手动滚动视图(或跳到特定位置)可以提供非常好的性能。
我们面临的问题是,在更高的速度下播放时会出现故障,这确实是一个小问题,但也是一个非常令人恼火的问题。我已经将原因缩小到我们在线程池线程中创建可写位图的那一刻。代码如下:
BitmapPalette bmp = new BitmapPalette(Palette);
WriteableBitmap wb = new WriteableBitmap(segment_bytes.ping_width, segment_bytes.height, 96, 96, System.Windows.Media.PixelFormats.Indexed8, bmp);
Int32Rect update_rect = new Int32Rect(0, 0, segment_bytes.ping_width, segment_bytes.height);
wb.WritePixels(update_rect, segment_bytes.data, segment_bytes.ping_width, 0);
wb.Freeze();
_element.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background,
new Action(delegate()
{
brush.set_image_brush(wb);
}));
set_image_brush调用仅设置笔刷的图像源,该笔刷用于渲染片段(通过drawRectangle)并启动短的不透明度动画。
通过反复试验(注释代码),我确定是WriteableBitmap的构造函数导致了每个段的速度减慢/故障,在较大的段上更为明显。因此,即使这一切都发生在线程池线程中,WB的创建也发生在渲染线程(UI线程?)上。
有什么办法绕过这个问题吗?
谢谢,马特
编辑:要绝对清楚的是,这是世界银行的创建造成的。如果我删除了在UI线程上设置图像的代码,并将片段渲染为轮廓矩形,我仍然可以看到小故障。同样,如果我删除writepixels调用。简单地创建WB就是造成这个问题的原因,我不知道该如何阻止它。。
尝试使用Dispatcher.CheckAccess()方法,如下所示:
if (_element.Dispatcher.CheckAccess())
{
new Action(delegate()
{
brush.set_image_brush(wb);
}));
}
else
{
_element.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background,
new Action(delegate()
{
brush.set_image_brush(wb);
}));
}