在不同线程中的渲染控制

本文关键字:控制 线程 | 更新日期: 2023-09-27 18:03:45

我有一个PDF导出在我的应用程序(migradoc)。为了避免冻结GUI,我想将此导出作为单独的线程运行。PDF中还嵌入了图表。为了使这些图表看起来像我在应用程序中使用的图表,我在代码中创建并渲染它们。(visifire)我的线程已经是STA,但我得到一个异常时运行WPF渲染命令:

调用线程不能访问这个对象,因为它被另一个线程拥有

我代码:

         chart.Measure(new Size(311, 180));
            chart.Arrange(new Rect(0, 0, 311, 180));
            chart.UpdateLayout();
            ExportToPng(new Uri("C:''" + i + "c.png"), chart);
  public void ExportToPng(Uri path, Chart surface)
    {
        if (path == null) return;

        // Save current canvas transform
        Transform transform = surface.LayoutTransform;

        // reset current transform (in case it is scaled or rotated)
        surface.LayoutTransform = null;

        // Create a render bitmap and push the surface to it
        var renderBitmap =
            new RenderTargetBitmap(
                (int) surface.Width,
                (int) surface.Height,
                96d,
                96d,
                PixelFormats.Pbgra32);

        renderBitmap.Render(surface);

        // Create a file stream for saving image
        using (var outStream = new FileStream(path.LocalPath, FileMode.Create))
        {
            // Use png encoder for our data
            var encoder = new PngBitmapEncoder();

            // push the rendered bitmap to it
            encoder.Frames.Add(BitmapFrame.Create(renderBitmap));

            // save the data to the stream
            encoder.Save(outStream);
        }

        // Restore previously saved layout
        surface.LayoutTransform = transform;
    }

我已经尝试调度这个命令,但我仍然得到相同的错误。

  DispatcherHelper.UIDispatcher.BeginInvoke((Action)(() =>
        {
                        chart.Measure(new Size(311, 180));
                        chart.Arrange(new Rect(0, 0, 311, 180));
                        chart.UpdateLayout();
                        ExportToPng(new Uri("C:''" + i + "c.png"), chart);
                    }));

在不同线程中的渲染控制

你需要传递任何对象的副本,这是GUI线程的一部分,因为GUI线程拥有它们,这就是为什么它们不能在其他线程中访问。就像你的图表对象一样,你需要创建一个图表对象的副本,然后将它传递给线程,所以对象的所有者是你的新线程。

如果你需要在同一个GUI线程上渲染这些,那么唯一的机会就是在同一个线程上渲染这些,然后等待操作完成。