1

WPF イメージングを使用して、DrawingVisual を使用してテキスト、3D グラフィックス、および画像を合成しています。結果は RenderTargetBitmap にレンダリングされ、jpeg としてディスクに保存されます。これらはすべて、ビジュアル ウィンドウのないコードで行われます。

一度に 1 つのことだけを実行しようとしている限り、うまく機能しています。ただし、複数のスレッドを使用してレンダリングを行うことで速度を上げることができるかどうかを確認したいと思います。各スレッドは、独自の DrawingContext、DrawingVisual などを作成するオブジェクトを使用します。ただし、並列にアクセスしようとすると誤ったエラーが発生するため、どこかに共有状態があることは明らかです。「別のスレッドが作成したため、呼び出し元のスレッドはこのオブジェクトにアクセスできません」という場合があります。また、たとえば 3D ジオメトリにポイントを追加しているときに、WPF の腸から NullReferenceExceptions が泡立ち、見た目が悪い場合もあります。

各スレッドが WPF で互いに離れていることを確認する方法はありますか? それとも共有状態は避けられないのでしょうか?

4

3 に答える 3

0

スレッド間で誤って同じリソースを使用している可能性はありますか? 処理コードに含まれるラムダ式または匿名メソッドはありますか?

于 2012-07-27T01:27:45.780 に答える
0

ユーレカ。私は threadpool スレッド内でオブジェクトを作成していましたが、これは WPF を使用する場合は明らかにノーです。代わりに、すべてのオブジェクトをディスパッチャ スレッドから作成する必要があります。ちなみに、これは私が発見していなかった恐ろしいメモリリークも解決しました。

私の元のクラス定義は次のようになりました。

public class Compositor
{
    private int _width;
    private int _height;
    private DrawingVisual _drawingVisual;
    private DrawingContext _drawingContext;
    private bool _isReady = false;
    public void Reset(int width, int height)
    {
        _width = width;
        _height = height;
        _drawingVisual = new DrawingVisual();
        _drawingContext = _drawingVisual.RenderOpen();
        _isReady = true;
    }
    // ... compositing methods below
}

修正するために、クラスに から継承DispatcherObjectさせ、プロパティを使用しDispatcherてオブジェクトをインスタンス化しました。

public class Compositor : DispatcherObject
{
    private int _width;
    private int _height;
    private DrawingVisual _drawingVisual;
    private DrawingContext _drawingContext;
    private bool _isReady = false;
    public void Reset(int width, int height)
    {
        Dispatcher.Invoke(
            new Action(
                () =>
                    {
                        _width = width;
                        _height = height;
                        _drawingVisual = new DrawingVisual();
                        _drawingContext = _drawingVisual.RenderOpen();
                        _isReady = true;
                    }));
    }
    // ... compositing methods below
}
于 2012-07-27T07:45:54.463 に答える
0

MSDNから:

DispatcherObject から派生したオブジェクトには、スレッド アフィニティがあります。

Freezable から派生したオブジェクトは、凍結されるとフリースレッドになります。詳細については、Freezable オブジェクトの概要を参照してください。

UI スレッドで (作成するだけでなく) 実際に使用する必要があるビットマップ、ブラシ、およびその他のクラスを操作するときに、同様の問題が発生しました。

WPF レンダリングの力を並列処理領域に活用したいので、これは面倒ですが、これは不可能のようです (WriteableBitmapポインターによる更新などのいくつかのシナリオを除く)。

于 2013-07-14T06:01:29.127 に答える