2013-03-13 90 views
2

我在我的應用程序(migradoc)中有一個PDF導出。爲了避免凍結GUI我想運行此導出爲單獨的線程。 PDF也嵌入了圖表。爲了使這些圖表看起來像我在我的應用程序中使用的那樣,我在代碼中創建並呈現它們。 (的Visifire) 我的主題已經是STA,但我得到運行WPF渲染命令時異常:Rendering Control in different Thread

,因爲不同的線程擁有它

我的代碼調用線程不能訪問該對象:

  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

AFAIK你只能在GUI線程上渲染GUI,而不能在其他線程上渲染。 – 2013-03-13 11:04:53

+0

我知道我已經嘗試調度它,但我仍然得到相同的錯誤(請參閱編輯) – TheJoeIaut 2013-03-13 11:08:10

+0

您的UI線程是否創建圖表對象?您只能從創建WPF對象的相同線程更新WPF對象。因此,如果您是從另一個線程創建圖表,那麼對該圖表對象的任何更新也需要位於該特定其他線程上。 – Rachel 2013-03-13 14:51:55

回答

0

你需要傳遞這是GUI線程的一部分的任何對象的副本作爲GUI線程擁有它們,這就是爲什麼他們不能在其他線程訪問。像圖表對象一樣,您需要創建圖表對象的副本,然後將其傳遞到線索中,以便對象的所有者是您的新線程。

如果您需要在同一個GUI線程上渲染它們,那麼只有在同一個線程上渲染它們並等待操作才能完成。

+0

I在單獨的線程中創建圖表對象。 – TheJoeIaut 2013-03-13 11:09:13

+0

@TheJoeIaut你不能在另一個線程上創建它並將其傳回,你應該在GUI線程上創建GUI元素。 – 2013-03-13 11:13:10

+0

背靠背只在GUI線程下工作。但是你可以用這種方式創建單向鏡頭。 – JSJ 2013-03-13 11:17:57

相關問題