2011-09-06 113 views
1

在.NET4.0 WPF中,我想使用後臺線程在畫布上顯示drawingPath。以下ConsumerJob在後臺正確運行並輪詢要繪製的點隊列。我使用Dispatcher來修改主線程上的畫布,並正確渲染它。不過,我希望這段代碼能夠在每個children.add被調用時(像動畫一樣)每次顯示一個片段。會發生什麼情況是整個顯示會一次渲染而不是一次一個渲染。我應該如何修改代碼來呈現顯示,因爲一次添加一個兒童?canvas未實時更新後臺線程

public void ConsumerJob() 
    { 

     while (true) 
     { 
      PointsD pt = (PointsD)queue.Consume(); 
      displayQueue.Enqueue(pt); 

      pt = Scale(pt); 

      this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, 
       (ThreadStart)delegate() 
       { 
        Path drawingPath = new Path(); 
        StreamGeometry streamingGeometry = new StreamGeometry(); 
        drawingPath.Stroke = Brushes.Black; 
        drawingPath.StrokeThickness = 0.5; 

        using (StreamGeometryContext ctx = streamingGeometry.Open()) 
        { 
          ctx.BeginFigure(new Point(pt.x0, pt.y0), false, false); 
          ctx.LineTo(new Point(pt.x1, pt.y1), true, false); 
        } 

        streamingGeometry.Freeze(); 
        drawingPath.Data = streamingGeometry; 

        this.Children.Add(drawingPath); 

       } 
       ); 

     } 
+1

其他選項可以一直使用'BackgroundWorker',它提供了3個事件,如DoWork的()(只有上面的委託代碼),ProgressNotified()(將在畫布的孩子)和WorkCompleted()(時間表接下來是bgworker的RunAsync()),這讓它感覺它是一個永久工作的線程,它會同步通知UI線程,以動畫的形式向畫布添加新的位。 –

回答

1

Dispatcher.BeginInvoke是異步的,你嘗試過它的同步對應Invoke

這應該至少強制所有排隊的委託按正確的順序執行,但不確定時間。

除此之外,您可能還想嘗試更高的DispatcherPriority。

+0

非常感謝。我將BeginInvoke更改爲Invoke,現在它可以正常工作。路徑得到實時顯示。正如你所說,我仍然對此感到驚訝,不清楚爲什麼這會影響時機。有用的,如果任何人有線索。 –

+0

@ChristopheBraun:那麼,BeginInvoke在排隊代理之後立即返回,所以所有更新很可能在一個週期內排隊並執行,讓您跳躍。調用等待正在執行的代理。另請參見[線程模型引用(http://msdn.microsoft.com/en-us/library/ms741870.aspx),但對這個隊列是如何工作的一些更多的信息。 –