Управление рендерингом в другой теме

У меня есть экспорт PDF в моем приложении (migradoc). Чтобы избежать зависания графического интерфейса, я хочу запустить этот экспорт как отдельный поток. В 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);
                    }));

1 ответ

Вам нужно передать копию любого объекта, который является частью потока GUI, поскольку поток GUI владеет ими, и поэтому они не могут быть доступны в другом потоке. подобно объекту диаграммы, вам необходимо создать копию объекта диаграммы и затем передать ее в поток, чтобы владельцем этого объекта был ваш новый поток.

Если вам необходимо отобразить их в одном и том же потоке графического интерфейса, то единственный шанс - отобразить их в одном и том же потоке и дождаться завершения операции.

Другие вопросы по тегам