【问题标题】:Rendering Control in different Thread在不同的线程中渲染控件
【发布时间】:2013-03-13 11:00:56
【问题描述】:

我的应用程序 (migradoc) 中有一个 PDF 导出文件。为了避免冻结 GUI,我想将此导出作为单独的线程运行。 PDF 还嵌入了图表。为了使这些图表看起来像我在应用程序中使用的图表,我在代码中创建和呈现它们。 (视火) 我的线程已经是 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);
                    }));

【问题讨论】:

  • AFAIK 您只能在 GUI 线程上渲染 GUI,而不能在其他线程上渲染。
  • 我知道我已经尝试发送它,但我仍然得到同样的错误(见编辑)
  • 您的 UI 线程是否创建图表对象?您只能从创建它们的同一线程更新 WPF 对象。因此,如果您从另一个线程创建图表,则对该图表对象的任何更新也需要在该特定的其他线程上。

标签: c# wpf multithreading visifire


【解决方案1】:

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

如果您需要在同一个 GUI 线程上呈现这些,那么唯一的机会就是在同一个线程上呈现这些并等待操作完成。

【讨论】:

  • @TheJoeIaut 您不能在另一个线程上创建它并将其传回,您应该只在 GUI 线程上创建 GUI 元素。
  • 背靠背只能在 GUI 线程下工作。但您可以通过这种方式创建一种方式的镜头。
  • 我试图实现的目标是将图表保存到文件中,然后将它们包含在报告中,而不会冻结我的 GUI。有没有办法在不同的 gui 线程上呈现图表。
  • 不,您不能在其他线程上呈现任何视觉类型的项目,您需要 GUI 线程。你可以做的一个模糊的事情。是在主线程上运行您的应用程序并运行另一个应用程序并呈现您的图表,然后只需复制它并按照您的喜好使用它。
猜你喜欢
  • 1970-01-01
  • 2021-02-16
  • 2015-09-05
  • 2013-01-30
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多