2011-09-09 5 views
4

私は、フォルダー内の画像を見つけて、どのように切り取るべきかをユーザーに提示する目的のアプリを書いています。私は日常的に言語から言語にいたるまでジャンプしているので、ベストプラクティスとコンセプトを混乱させる傾向があります。このようなケースです。イメージを一度ロードして、マルチスレッドのC#アプリケーションでそれを渡す方法はありますか?

プログラムの流れは次のようになります。メインフォームが表示され、ブラウズボタン(フォルダをドロップすることもできます)が表示されます。フォルダを選択すると、選択したフォルダの.jp [e] gと.tif [f]画像をスキャンして一覧に表示し、どの画像を切り抜きたいのかを尋ねる別のフォームが開きますオプション。その後、メインフォームに戻り、そのフォームから選択した画像のリストを表示し、それぞれの画像の中にBackgroundWorkerを入れてクロッピングフォームにロードし、クロップして保存します。

プロトタイプ作成のために私は画像の読み込みを混乱させる。選択フォームのフォルダ内のすべての画像がロードされた後、選択された各画像がクロッピングで1つずつ読み込まれ、もう一度メインフォームでトリミングされて保存されます。大きな画像の場合、このアプリケーションはTIFFソース画像を最悪の場合のシナリオで約4000px まで扱うため、タスクに時間がかかる可能性があります。

Bitmapを一度グローバル配列にロードする方法があると思いますが、これはVisual BasicまたはVB for Applicationsになります。私はBackgroundWorkerを使用しているので、スレッドの安全性と、安全でない方法で何かにアクセスしようとすることについてC#が怒鳴るかどうかについても心配する必要があります。単一の画像がBitmapオブジェクトに読み込まれる回数を制限しながら、アプリの目的をどのように達成できるかについてのアイデアはありますか?

答えて

1

Microsoftに応じBitmapクラスのインスタンスメンバーがスレッドセーフであることが保証されていないので、私は2つのオプションを参照:Bitmapオブジェクトとしてパフォーマンスが、少し危険な
ロードすべて

  • をし、すべてのそれらを追加ビットマップオブジェクトなど、すべてのファイルをロード ConcurrentDictionary ...実装は、主にロックフリーであるため、アクセスが...少し小さいパフォーマンスではなく、危険な

  • スレッドセーフ非常に高速である
    へをConcurrentDictionaryに変換します。ビットマップが必要なときは、MemoryMappedFileを作成するだけです(これはすでに作成されたワンセグによって作成された同じメモリを非常に高速で使用します)。そして、ビットマップがそこからコンテンツを読み込ませるようにします...あなたのアプリケーションがシャットダウンしたとき、私は何もしているように周りのオブジェクトを渡すための心の中でこれらのメソッドをしておこう

1

次の2つのオプションがあります:1つの以上の他のよりも、オブジェクト指向が、実装が困難:

A)を、あなたのすべてを追加リストを保持する(例えば、文書、BitmapDocument、または何でも)いくつかのクラスを作成します。画像。マルチスレッドについて心配する必要はありません。イメージを追加するたびにListをロックするだけです。ビットマップで何をするかによって、それらをロックする必要があるかもしれません。別のコントロールが使用するビットマップ(すでにリストにロードされている)のコピーを作成するには、あまりにも多くのメモリ/時間を必要としないはずですRAM操作になります)。問題は、メインアプリケーションがこの "ドキュメント"クラスをすべての子コントロールとフォームに渡さなければならない場合に発生します。すべてのコントロールが「ドキュメント」インスタンスを認識すると、そのドキュメントへの追加はすぐに利用できます。

B)Listが内部および静的とマークされているクラスを作成します。これにより、プロジェクト内のどのクラスでもそれを表示して使用できるようになります。この方法では、一種の「グローバル」配列を使用していますが、まったくグローバルではありません。それはあなたのプロジェクトの内部でしか見えません( "内部"タグのため)、それはまだクラス内に保持されています。すべてのスレッドを安全にするためには、C#のロック機構を使用する必要があることに注意してください。

クラスメンバーに直接アクセスするのではなく、クラスメンバーを操作してオブジェクトを適切にロックするメソッドを記述することを検討してください。 (これは正しいプログラミングの練習になります)。Bでは、 "internal"と "static"とマークされたメソッドを作成するだけです。

私は個人的には、プロトタイプ作成のために特にB(実装とデバッグに手間がかかりません)を使用しています。これを使用すると、今後Aに移行するのが難しくなりません。

さらに、(B)の内部静的オブジェクトと関数のアプローチを使用すると、ディスクからイメージをロードするGetBitmap(文字列パス)のような関数を書くことができます。スレッドはディスクから2回ロードする必要はありません。

+0

あなただけの辞書を通過し、それらのMemoryMappedFileオブジェクトを取り除く清掃...私は...としてそれが通されていない書きます以下のYahiaは、インスタンス化されたビットマップはスレッドセーフであるとは保証されていません。リスト(T)もそうではないことがわかりました。 –