1

WPF ウィンドウ内にキャンバスがあり、膨大な数の形状 (約 10 万以上の形状) を描画したいと考えています。このようなもの:

<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);
}

次に、たとえば 40,000 個の図形を描画するには、次のようにします。

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: パフォーマンス上の理由から、ShapeオブジェクトではなくVisualを使用して図形を描画します。

4

2 に答える 2

0

私の知る限り、WPF(3.5まで)にはWPFオブジェクトにアクセスできるスレッドが1つしかないため、スレッドではなく最適化する必要があると思います。

たとえば、すべての図形を一緒に表示する必要がありますか? それらのサブセットのみをロードし、他のオブジェクトを 2 回目にロードできますか?

于 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 に答える