如何在非UI线程中编辑WritableBitmap.BackBuffer?

Vas*_*iak 6 .net c# wpf

我的应用程序运行CPU密集的algorythms来编辑放置在WPF窗口的图像.我需要在后台线程中完成编辑.但是,尝试在非UI线程中编辑WritableBitmap的BackBuffer会引发InvalidOperationException.

    private WriteableBitmap writeableBitmap;

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        // Create WritableBitmap in UI thread.
        this.writeableBitmap = new WriteableBitmap(10, 10, 96, 96, PixelFormats.Bgr24, null);
        this.image1.Source = this.writeableBitmap;

        // Run code in non UI thread.
        new Thread(
            () =>
            {
                // 'Edit' bitmap in non UI thread.
                this.writeableBitmap.Lock(); // Exception: The calling thread cannot access this object because a different thread owns it.

                // ... At this place the CPU is highly loaded, we edit this.writeableBitmap.BackBuffer.

                this.writeableBitmap.Unlock();
            }).Start();
    }
Run Code Online (Sandbox Code Playgroud)

我已阅读了几十本手册,所有这些手册都告诉我在UI线程(即MSDN)中执行BackBuffer版本.

如何在非UI线程中编辑WritableBitmap.BackBuffer而不进行任何无用的缓冲区复制/克隆?

LOA*_*OAS 11

MSDN建议在后台线程中写入后备缓冲区.只需要在UI线程上执行某些更新前和更新后操作.因此,当后台线程正在进行实际更新时,UI线程可以自由地执行其他操作:

        //Put this code in a method that is called from the background thread
        long pBackBuffer = 0, backBufferStride = 0;
        Application.Current.Dispatcher.Invoke(() =>
        {//lock bitmap in ui thread
            _bitmap.Lock();
            pBackBuffer = (long)_bitmap.BackBuffer;//Make pointer available to background thread
            backBufferStride = Bitmap.BackBufferStride;
        });
        //Back to the worker thread
        unsafe
        {
            //Carry out updates to the backbuffer here
            foreach (var update in updates)
            {
                long bufferWithOffset = pBackBuffer + GetBufferOffset(update.X, update.Y, backBufferStride);
                *((int*)bufferWithOffset) = update.Color;
            }
        }
        Application.Current.Dispatcher.Invoke(() =>
        {//UI thread does post update operations
            _bitmap.AddDirtyRect(new System.Windows.Int32Rect(0, 0, width, height));
            _bitmap.Unlock();
        });
Run Code Online (Sandbox Code Playgroud)