Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在后台线程上创建位图会暂停渲染线程_C#_Wpf_Multithreading_Graphics - Fatal编程技术网

C# 在后台线程上创建位图会暂停渲染线程

C# 在后台线程上创建位图会暂停渲染线程,c#,wpf,multithreading,graphics,C#,Wpf,Multithreading,Graphics,一点背景:我正在制作声纳记录回放的显示动画。声纳记录文件很大(通常为100-600MB),因此根据需要加载段。它的核心是我们预先索引声纳文件,然后使用内存映射文件根据需要加载数据块。然后,数据被用来创建位图——非常简单,因为数据由字节组成,我们只是使用8位调色板将这些字节映射到颜色 出于性能原因,我们在后台执行所有加载,并在其自己的图形视觉中渲染每个片段。这很好,手动滚动视图(或跳到特定位置)可以提供非常好的性能 我们现在面临的问题——这确实是一个小问题,但也是一个非常令人恼火的问题——是我们在

一点背景:我正在制作声纳记录回放的显示动画。声纳记录文件很大(通常为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_笔刷调用仅设置用于渲染分段(通过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);
            }));
        }

直接(通过)创建位图源,而不是创建一个WriteableBitmap,然后调用WritePixels,怎么样?值得一试Clemens,但不幸的是,行为完全相同。重用现有WriteableBitmaps有意义吗?或者它们每次的大小都不同吗?不幸的是,它们的大小范围很广,并根据需要创建和销毁..嗨,帕拉克-只是澄清一下,这不是导致问题的代码部分。这是在位图本身的创建过程中-如果我完全注释掉画笔设置,我仍然会减慢速度。无论如何,谢谢你。