1

我的 WPF 窗口中有一个画布,我想绘制大量形状(大约十万个或更多)。像这样的东西:

<Window>
<Canvas>
    <!--<Shape1/>
    <Shape2/>
    ... and so on ... -->
</Canvas>
</Window>

要绘制形状,我有一种方法可以完成这样的工作:

public void DrawShape()
{
    // Create the shape
    ShapeT MyShape = new ShapeT();
    // Set shape's properties (like Width, Fill, ...)

    // Add shape as MyCanvas children.
    MyCanvas.Children.Add(MyShape);
}

然后画,例如,我做的四万个形状:

for (uint i = 0; i < 0x9C40; ++i)
     DrawShape();

问题是:

  1. 直到没有绘制所有图形,即直到循环完成,没有绘制图形并且我的窗口一直没有响应。

  2. 即使循环完成后,仍然需要几秒钟才能在视频上绘制数字,并且我的窗口继续被冻结。

我尝试使用Dispatcher

Dispatcher.BeginInvoke(DispatcherPriority.Background, new MyDrawDelegate(DrawShape));

我试图创建一个新线程:

Thread DrawThread = new Thread(new ThreadStart(DrawShape));
DrawThread.SetApartmentState(ApartmentState.STA);
DrawThread.Priority = ThreadPriority.Lowest;
DrawThread.Start();

但没有任何变化。我该如何解决这些问题?

PS:出于性能原因,我使用Visual而不是Shape对象绘制我的形状。

4

2 回答 2

0

据我所知,WPF(直到 3.5)只允许一个线程访问 WPF 对象,所以我认为您需要优化它而不是使用线程。

例如:您是否需要将所有形状都显示在一起?您可以仅加载其中的一个子集并在第二次加载其他一些对象吗?

于 2012-04-21T17:25:22.820 回答
0

当您使用 Dispatcher 时,您的 ArangePass 可能需要很长时间才能将更新的更改呈现到 UI。您可以通过添加以下代码片段让您的父容器等待:

  using (var temporaryPresentationSource = new HwndSource(new HwndSourceParameters()) { RootVisual = (VisualTreeHelper.GetParent(yourRenderTarget) == null ? yourRenderTarget: null) })
        {
            // Flush the dispatcher queue
            yourRenderTarget.Dispatcher.Invoke(DispatcherPriority.Background, 
            new Action(() => {/*required action*/ }));
         }

试一试,它对我有用.. !!

于 2012-04-21T17:52:56.837 回答