2009-08-03 3 views
1

現在、多くの異なるファイルからのデータのレンダリングが必要なWPF(C#の裏側)システムで作業しています。これらのファイルのほとんどはAutoCADドキュメントです。各ファイルには、基本的に同じキャンバス上に描画する必要がある一連のデータが用意されています。各ファイルは、画面に表示する必要がある潜在的な「レイヤー」またはオーバーレイと考えてください。異なるスレッドでのパスの作成と同じキャンバスへのレンダリング

現時点では、各グラフィックスソースは解析され、Pathオブジェクトのセットに変換されます。パスの各コレクションは、自身のCanvasにレンダリングされ、可視性をオンまたはオフに切り替えることができます。これらのキャンバスはそれぞれ親キャンバスの子になり、そのキャンバスには一連の変換が適用されます。これらの変換は基本的なスケールであり、変換されたレンダリング変換は表示されている画像のパンおよびズームをサポートするために使用されます。

この機能は現在問題なく動作していますが、遅いです。私たちは画面上にかなりの数のPathオブジェクトをレンダリングしており、それらのPathインスタンスのロード/作成にはかなりの時間がかかります。

ロードスピード自体はそれほど問題ではありません。実際に問題があるのは、UIスレッドでPathインスタンスを作成する必要があるということです。そうしないと、すべて同じキャンバスにレンダリングできません。したがって、読み込み中にのUI全体がロックされてとなり、ユーザーは何もできません。

私はウェブ上で広範に検索しましたが、問題の解決策を見つけることができませんでした。同じ記事の別のスレッドで作成されたアイテムをホストする方法を記述した記事(残念ながら私はもうリンクがありません)につきました。ウィンドウ。これは私のためには全く役に立たなかった。私は記事で見つけたものの組み合わせを試しましたが、レンダリングするためのものは何も得られませんでした。

私の質問の要点は、UIオブジェクトのセット、特にパスオブジェクトを別のスレッドに作成し、メインUIスレッドの親キャンバスにロードしてそれらをすべて持たせることができるかどうかです一緒にきれいに遊ぶ?すべての参考文献、記事またはチュートリアルは非常に高く評価されます。

私はあなたの助けを楽しみにしています!読んでくれてありがとう。

OJ

編集1:パスの各インスタンスには、カラーで1行だけです。彼らは複雑ではありません。しかし、それらのオブジェクトの作成自体は、時間を取っていることです(私は間違っているかもしれません)。ありがとう!

+0

要するに、バックグラウンドスレッドの要素を私が望むように作成することができません。しかし、私は他の種類の要素を作成し、それらをフリーズし、それらをメインのUIスレッドで利用することができます。それは完璧な解決策ではありませんが、私はそれを行う他の方法を見ることはできません。誰にも感謝してくれました。 –

答えて

1

PathGeometry(作業の大部分)を別のスレッドに作成し、フリーズし、UIスレッドで作成されたパスに設定することも可能です。

FreezableオブジェクトのMSDN articleです(PathGeometryは1つですが、一度固定されたスレッド間で共有できますが、変更されていないことを示しています)。 。これはあなたのシナリオに合っているかもしれません。

+0

ベン、お返事ありがとうございます。私はそれらを凍結することを見てみましょう。私は過去にこのルートを見ていたが、何らかの理由でそれを割り引いた(正当な正当な理由なしに)私はそれを試して、私はどうやって行くのか見ていきます。乾杯。 –

+0

ああ、なぜ私はそれを割り引いたのか分かっていると思う。 PathGeometryはフリーズできますが、Pathは取得できません。私は間違っていますか? –

+0

はい、あなたは正しいです(答えが更新されました)が、別のスレッドでPathGeometryを作成してフリーズし、UIスレッドで作成したパス(データメンバー経由)に設定することができます。 –

0

すべてのUIElementにDispatcherが存在し、正しいスレッドでコードを実行するためのBeginInvokeメソッドを提供していますか? Build More Responsive Apps With The Dispatcher

のWindows Presentation Foundationのスレッドモデルがhereに記載されている:

は、このMSDNの記事を読みました。

+0

応答のためにありがとうMitch。 ディスパッチャは実際には入っていません。ディスパッチャは、他のスレッドで作業を完了したときにUIを更新するために使用されるものです。私の場合はこのシナリオに合っていません。私は、別のスレッドでUIオブジェクトを作成してから、UIスレッドに戻す必要があります。私はただのバックグラウンド作業をしているだけではありません。乾杯。 –

+0

PS。はい私はすでにその記事を読んでいます:)それは私の場合に役立ちません。ありがとう! –

0

単なるアイデアです。 UIオブジェクトを扱う代わりに、XAMLを使用するとどうなりますか?単なる文字列です。たとえば、アプリケーションが起動すると、ファイルごとにバックグラウンドスレッド(BackgroundWorker)が生成されます。バックグラウンドワーカーはファイルを読み取り、ルートUI要素としてキャンバスを持ち、データから生成されたパスを持つXAMLをまとめます。そのXAMLを文字列としてUIスレッドに返します。 UIスレッドは、XamlReader.Loadメソッドを使用してXAMLを読み込み、結果のキャンバスオブジェクトを親キャンバスに追加します。ワーカースレッドにUI要素(子キャンバスとその中に含まれるパス)を作成し、その結果のXAMLを取得してメインスレッドに戻すこともできます。

+0

メフメット、ご返信ありがとうございます。それは興味深い考えです。パフォーマンスの意味合いは分かりませんが、それは価値があるかもしれません。私がベンの提案と一緒に演奏を終えると、私はこれも渦巻きにするでしょう。乾杯! –

関連する問題