web-dev-qa-db-ja.com

C#に自動ディスパッチャーがないのはなぜですか

なぜC#makeは、UIを更新するために別のスレッドのディスパッチャーを配置するのですか?

例:

Dispatcher.Invoke(() =
{
    lblerrorName.Content = "";
});

常に「別のスレッドで実行中」という例外が発生しますが、UIスレッドにあるラベルを変更したい場合は、それが自動的に舞台裏で行われるのはなぜですか。

それは明白な理由なしに複雑さと追加のコードを追加します、なぜそれがこのようなものであるか誰かが説明できますか?

2
hunterzzpro

なぜそれが自動的に舞台裏で行われないのですか?.

これは、1つのコンポーネントの1つのプロパティに対して1つのアクションのみが関係している限り機能しますが、アクションが増えると、おそらく相互に依存するアクションが増えると、競合状態に陥るリスクが高くなります。明示的な「呼び出し」メカニズムは、トランザクションブラケットのように機能し、プログラマがアトミックの方法で複数のステートメントをグループ化できるようにします。

たとえば、WPFが「舞台裏」でコントロールアクションを呼び出す場合、各コントロールプロパティへのアクセスはそれ自体で遅延アクセスになります。これは、次のようなコードに非常に奇妙な効果をもたらします。

 lblerrorName.Content = "ABC"; // this assignment is deferred 
 // ...
 lblerrorName.Content = lblerrorName.Content + "DEF"; // "ABCDEF"? Maybe not.

このようなコードは、UIスレッド、UIスレッド外、またはデバッガーで段階的に実行すると、異なる動作を生成する可能性があります。

ただし、明示的な呼び出しにより、プログラマーはさまざまなコンポーネント操作ステートメントを意図的にまとめることができます。

Dispatcher.Invoke(() =
{
    lblerrorName.Content = "ABC";
    //...
    lblerrorName.Content = lblerrorName.Content + "DEF";  // "ABCDEF"
});

したがって、これは自動化よりもエラーが発生しにくい方法です。

副次的なポイントとして、複数の制御データを操作する必要があるシナリオでは、おそらくループ内で、自動呼び出しは著しくパフォーマンスに影響を与える可能性があります。

4
Doc Brown

プログラムが非UIスレッドからUIを更新したい場合、アプリケーションフレームワークには2つの選択肢があります。

  • uIスレッドがイベントを待機するまで非UIスレッドをブロックし、非UIスレッドが更新を完了するまでUIスレッドをロックアウトします。
  • 非UIスレッドに更新を遅延アクションとして指定させます。つまり、都合の良いときにUIスレッドによって実行できるいくつかのコードです。

後者のオプションは、非UIスレッドを続行し、場合によっては順次実行できる更新をさらに指定できるため、より用途が広いです。また、どちらのスレッドもリソースロックを保持している可能性がある間、他のスレッドを待機する必要がないため、デッドロックの問題を回避できます。

これらがC#フレームワークがDispatcherアプローチを使用する主な理由であると思います。

2

スレッドセーフの場合:WPFコントロールで使用されるスレッドアパートメントはSTAであり、コンポーネントを作成したスレッドのみがコンポーネントを変更できます。これは、継承してスレッドセーフではないオブジェクトのスレッドセーフを高めるために行われます。

バックグラウンドスレッドで何かを変更すると、プログラマに代わってスレッドエラーが発生する可能性があります。そのため、例外が発生し、元のSTAスレッドにマーシャリングし直す必要があります。自動ディスパッチがあると、この目的は実質的に無効になります

1
Ccm

C#コンパイラを想定していて、IDEは、何をしていて、どのような目的であるかを認識しているか、または認識している必要があります。C#コンパイラは第3世代プログラミング言語です。そうではありません。わかりました。 IDE= WPFアプリケーションまたはWindowsフォームアプリケーションを実行しているため、テンプレートを使用すると、すぐに開始でき、ガイダンスが得られます。ただし、スレッドセーフな操作とそうでない操作を知ると、特定のシナリオでこれらを処理する方法には、非常に多くのインテリジェンスが必要です。C#コンパイラとIDEはドキュメントを読みません。もしそうなら、おそらく、それらが物事を処理する方法に同意しないでしょう。とにかく、彼らが行った選択を使用します。

0
Martin Maat