一些背景知识:我正在为声纳记录回放的显示制作动画。声纳记录文件很大(通常为 100 - 600MB),因此根据需要加载片段。它的核心是我们预先索引声纳文件,然后使用内存映射文件根据需要加载数据 block 。然后使用数据创建位图 - 非常简单,因为数据由字节组成,我们只需使用 8 位调色板将它们映射到颜色。
出于性能原因,我们在后台进行所有加载,并在其自己的绘图视觉中渲染每个片段。这工作正常,手动 ScrollView (或跳转到特定位置)提供非常好的性能。
我们遇到的问题 - 这确实是一个小问题,但却是一个非常恼人的问题 - 是我们在更高速度下播放时出现故障。我已经将原因缩小到我们在线程池线程中创建可写位图的那一刻。代码如下:
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 线程?)上。
有什么办法可以解决这个问题吗?
谢谢, 马特
编辑:明确地说,是 WB 的创建导致了这一点。如果我删除代码以在 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);
}));
}
关于c# - 在后台线程上创建位图会停止渲染线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22935617/