2

BeginInvoke デリゲート呼び出しを使用して別のスレッドから更新されるサード パーティのイメージ表示コントロールを含む Windows フォーム ユーザー コントロールがあります。

CPU 負荷が高い場合、UI がロックアップします。デバッガーをアタッチすると、サードパーティのイメージ コントロールを更新しているコードの同じ行に常に表示されます。

    public ICogImage DisplayImage
    {
        get { return this.ResultImageCogDisplay.Image; }
        set 
        {
           this.BeginInvoke((ThreadStart)delegate
            {
                this.ResultImageCogDisplay.Image = value;
            });

        }
    }

セッターの実装をコメントアウトすると、問題はなくなります。

なぜこれが起こっているのか誰でも説明できますか?

いくつかの詳細情報:

  • 画像更新イベントは、フレーム グラバー カードから定期的に (~200ms) 生成されます。イベントは別のスレッドで発生します。
  • サードパーティのイメージ コントロールは ActiveX を使用していると思います。これは Cognex のビジョン処理フレームワークの一部です。
  • 画像は約です。900x800 8 ビット グレースケール
  • フォームにはこれらのコントロールが 4 つあり、それぞれが異なる画像の異なるスレッドから供給されます。
  • IsInvokeRequired() チェックの有無にかかわらず試してみましたが、違いはないようです。

CPU 負荷が高い状態でヒットしている PostMessage キューのメッセージ数に制限はありますか?

4

2 に答える 2

4

BeginInvokeUI スレッドで実行されるアクションをキューに入れます。UI が追いつかないほど多くのことをキューに入れると、UI スレッドに圧倒され、ハングしているように見えます。イベントをおそらく 1 秒に 1 回に調整して、それが役立つかどうかを確認してください。

于 2012-08-14T23:07:53.630 に答える
0

実際、Windows Message Queue エントリには 10,000 エントリの制限があります (少なくとも 32 ビット システムにはあります)。それが起こるずっと前に、GUI が処理できるよりも速くメッセージを投稿することによって、GUI を占有することは非常に簡単です - 私はこれを頻繁に行いました:((

通常、私の設計ではスレッド間通信にオブジェクトのプールを使用するため、GUI が「使用済み」オブジェクトを十分に速く返さないとプロデューサー スレッドがプール キューでブロックされるため、この問題を回避し、全体的なフロー制御を提供します。 . もちろん、GUI のロックアップを停止している間は、満たすことができないフレームレート要件がある場合、これはあまり役に立ちません:(

于 2012-08-14T23:45:59.820 に答える