2

現在、Windows.Formsアプリケーションに取り組んでいます。これは基本的に単純な動き検出の問題です。

フォームにボタンがあり、押すと次のことを行うバックグラウンドワーカーが起動します。

  1. ディスクから画像を取得する
  2. バッファとして使用する新しいビットマップを作成します。
  3. モーション検知を実行する
  4. モーション検知の結果から、バッファを更新します(バッファの描画面を使用)
  5. 基本的に、バッファのクローンで構成される引数を使用してProgressChangedイベントを発生させます(sender as BackgroundWorker).ReportProgress((Bitmap)buffer.Clone())

次に、Progress Changedイベントで、バッファを画面に描画します。

if (!PnlImage.IsDisposed)
            PnlImage.CreateGraphics().DrawImageUnscaled(buffer, 0, 0);

これが更新された画像を画面に描画するための最良の方法であるかどうか疑問に思わずにはいられません。誰かが私ができる改善を提案できますか?ありがとう。

編集:その後、.NET Framework 4を使用するようにプログラムを更新しましたが、BackgroundWorkerは使用していません。代わりに、System.Threading.Tasks名前空間を使用し、Invokeを使用してタスク内から背景画像を更新しています。

すべての返信に感謝します。

4

4 に答える 4

2

発生している可能性のある問題の根本は、GUIの更新をUIスレッドで実行する必要があるという事実にあると思います。別のスレッドからUIを安全に更新することはできません。したがって、基本的には、次のようなことを行う必要があります(例として背景色を変更しているだけですが、好きなように行うことができます)。

    private void SomethingCalledFromBackgroundThread()
    {
        panel1.Invoke(new DoUpdatePanel(UpdatePanel), Color.Blue);
    }

    private delegate void DoUpdatePanel(Color aColor);

    private void UpdatePanel(Color aColor)
    {
        panel1.BackColor = aColor;
    }

============更新=======>

@Ashあなたは私の答えを誤解しました。ProgressChanged内からInvokeを呼び出すとは言いませんでした。@Jeanは、ReportProgress / ProgressChangedが非同期で実行されていることを覚えておいてください。これが、イメージのクローンを作成している理由です。ReportProgressではなく、バックグラウンドスレッド内からInvokeを使用する場合、これは必要ありません。

于 2010-01-10T02:10:03.667 に答える
1

これが厳密に正しいかどうかはわかりませんが、専用のGUIスレッドでデフォルトで処理されるため、別のスレッドでGUI/制御操作をクロススレッドすることはできないと確信しています。

以前はこれに似たようなことをしようとしましたが、プロパティをfalseに設定することがそれを機能させるための最悪の方法であったため、最終的にはまったく異なるアプローチを決定しました。

于 2010-01-10T00:54:53.570 に答える
1

ProgressChangedイベントとRunWorkerCompletedイベントを使用すると、UIを直接更新できます。からアクセスしてはならないのは、DoWorkイベントハンドラーのみです。 MSDNを参照してください

DoWorkイベントハンドラーでユーザーインターフェイスオブジェクトを操作しないように注意する必要があります。代わりに、ProgressChangedイベントとRunWorkerCompletedイベントを介してユーザーインターフェイスに通信します。

これは、独自のスレッドを作成するよりもBackgroundWorkerを使用することの主な利点の1つです。したがって、TheObjectGuyは正しくありません。ProgressChangedでBeginInvoke/Invokeを使用する必要はありません。

イメージが大きすぎない限り、クローンを作成しても重大なパフォーマンスの問題は発生しません。懸念がある場合は、より大きなイメージでいくつかのパフォーマンステストを実行してください。

それ以外の場合は、ロックの使用などのトリッキーな同期の問題を回避するために、イメージのクローンを作成することは、物事を単純に保つための良い方法だと思います。

于 2010-01-10T05:57:13.367 に答える
1

ProgressChangedイベントの使用は問題ありません。うまくいかないのは、画面に直接描画することです。フォームを最小化して復元すると、画像が消えます。回避策は簡単です。

 PnlImage.BackgroundImage = buffer;
于 2010-01-11T16:53:02.223 に答える