2

これを使用して、別のスレッドからメイン スレッドのコントロールを更新しています。

private void ShowHourGlassSafe(bool visible)
{
    this.Invoke((EventHandler)((s, ev) => pictureBoxHourGlass.Visible = visible));           
}

このようにすることの意味は何ですか、またはこれが失敗するリスクはありますか?

多くの例から、私はこのようなものを見つけることができませんでした。

単純に間違っているのではないでしょうか?

4

2 に答える 2

3

さて、あなたは選択するのにかなり奇妙なデリゲートを選びました。何も必要でなく、提供されないという事実にもかかわらず、2つのパラメーターを持つものを選んだからです。それがそれを壊す原因になるかどうかはわかりませんが、それは確かに何の助けにもなりません。次のように、パラメータを受け取らず、値を返さないデリゲートを使用するのが最善の方法です。

private void ShowHourGlassSafe(bool visible)
{
    this.Invoke((MethodInvoker)(() => pictureBoxHourGlass.Visible = visible));           
}

それ以外は、あなたがしていることの基本的な概念は完全に素晴らしいです。

于 2013-02-21T15:26:26.573 に答える
2

この種のコードの典型的な問題:

  • UIスレッドがスレッドの完了を待つなど、賢明でないことをしていると、デッドロックが発生します。Invokeを使用しても意味がありません。これは、ワーカースレッドをブロックして利益をもたらさないため、BeginInvokeを使用するだけです。デッドロックの可能性と不要な遅延を解決します。

  • UIが閉じられ、pictureBoxHourGlassが破棄されると、クラッシュします。UIを閉じる前にスレッドが実行されていないことを確認することは、非常に一般的に見過ごされています。砂時計を表示するだけでは不十分であり、ユーザーがUIを閉じないように対策を講じる必要があります。または、最初にスレッドをキャンセルする方法と連動させます

  • ユーザーは通常、砂時計が表示されたときに、何かが行われたことを尋ねるために何もしなくても混乱します。99%正しいケースは、UIスレッドにコード付きの砂時計を表示してから、スレッドを開始することです。そして、スレッドが完了したら、もう一度非表示にします。BackgroundWorkerクラスまたはTaskクラスを使用するのが最も簡単で、ジョブの完了後にUIスレッドでコードを実行できます。

一貫性を保つために、アクションデリゲートタイプを優先します。

    private void ShowHourGlassSafe(bool visible) {
        this.BeginInvoke(new Action(() => something.Visible = visible));
    }
于 2013-02-21T15:38:34.833 に答える