将 WriteableBitmap 线程化到 Image 控件

Threading WriteableBitmap to Image control

我在 .NET Core 3.1 平台上使用 OpenGL 在 WPF 中渲染静态图片。上下文最初显示在隐藏的 GLFW window 中。然后我使用 glReadPixels 读取上下文并将其显示在 UI 上的图像控件上,代码如下所示。不使用线程时,代码工作正常。但是,当通过不同的线程调用渲染代码时,图像不会显示。作为中间检查,我创建了 using (FileStream... 代码,它读取 WriteableBitmap 并将其保存在本地并且似乎工作正常;这意味着 WriteableBitmap 已正确创建。所以,我想问题是如何将 WriteableBitmap 传输到 Image 控件,这两者都是在不同的线程上创建的。 Dispatcher.BeginInvoke 由于某些奇怪的原因无法正常工作。

    byte[] imageBuffer = new byte[imageWidth * imageHeight * 4];
    glReadPixels(0, 0, imageWidth, imageHeight, GL_BGRA, GL_UNSIGNED_BYTE, imageBuffer);
    imageBuffer = ImageReverse(imageBuffer, imageWidth);
    PixelFormat pixelFormat = PixelFormats.Pbgra32;
    int rawStride = (imageWidth * pixelFormat.BitsPerPixel) / 8;
    BitmapSource bitmapSource = BitmapSource.Create(imageWidth, imageHeight, 96, 96, pixelFormat, null, imageBuffer, rawStride);
    WriteableBitmap writeableBitmap = new WriteableBitmap(bitmapSource);

    //This is a check whether the writeableBitmap has been created correctly
    using (FileStream fileStream = new FileStream(@"C:\Temp\Image1.bmp", FileMode.Create))
    {
        BmpBitmapEncoder encoder = new BmpBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(writeableBitmap));
        encoder.Save(fileStream);
    }

    Action action = new Action(() => {
        _imgSoilProfile.Source = writeableBitmap; 
    });
    _imgSoilProfile.Dispatcher.BeginInvoke(action, DispatcherPriority.Send);

在设置 ImageSource 之前尝试在后台线程上调用 w.Freeze():

using (FileStream fileStream = new FileStream(@"C:\Temp\Image1.bmp", FileMode.Create))
{
    ...
}
w.Freeze();

Action action = new Action(() => {
    _imgSoilProfile.Source = writeableBitmap; 
});

来自docs

A frozen Freezable can also be shared across threads, while an unfrozen Freezable cannot.