Microsoft-ui-xaml: 提案:自動ディスパッチプロパティにより、イベントがUIスレッドに変更されました

作成日 2019年05月17日  ·  3コメント  ·  ソース: microsoft/microsoft-ui-xaml

概要

UI以外のスレッドからの通知変更を発生させるプロパティからUIバインディングが発生することを許可します

理論的根拠

プロパティをバインドするときは、常にUIスレッドでプロパティ変更通知を発生させる必要があります。そうしないと、実行時例外が発生します。 これにより、UIがビューモデルとモデルにブリードし、適切なスレッドでレイズできるようになります。これにより、.NET標準ライブラリからINPCを使用できなくなります(ベイトアンドスイッチを使用する場合を除く)。 。

さらに、1つのフレーム中にプロパティが複数回変更される可能性があるため、実際に必要な回数よりも多くの回数UIスレッドにジャンプする可能性があります(必要なのは、プロパティに「ダーティ」のフラグを付けて、次のレンダリングパス。

これにより、コードが大幅に複雑になり、エラーが発生しやすくなります。

また、WinUI 3.0でも問題が発生します。これは、レガシーUWPスレッドとWinUIスレッドの2つのUIスレッドがあるためです。どちらを上げる必要がありますか?

範囲

  • 任意のスレッドでINotifyPropertyChangedおよびINotifyCollectionChangedを発生させることができる必要があります
  • フレーム内で複数回安価に実行できる必要がありますが、1回の更新のみをトリガーします(最後の更新が勝ちます)
  • UIを更新するために読み取られている間に、設定されているプロパティを処理できる必要があります。
  • UIスレッドがすでに存在する場合は、UIスレッドへの切り替えを回避します。

重要な注意事項

糸脱毛の懸念はもちろん有効ですが、これが最終的には本当に問題になるとは思いません。 UIが更新される前に複数のINPCイベントが発生することは問題ではありません。これは、最後のイベントのみが問題になるためです。 これは、UIスレッドに複数回切り替える既存のコードと同じです。 最初のスレッドがUIスレッドに切り替わると、プロパティはすでに何度も更新されている可能性があるため、最後の1つが勝ちです。
当然、値が読み取られるときにダーティフラグが設定されないようにする短いロックが必要になるため、プロパティが読み取られると同時にプロパティが更新された場合は、次のフレームで2回目のUI更新が行われます。
実際、たとえば値がfalseからtrueに変更され、falseに戻る場合、Dependencyプロパティは、値が変更されていないことを検出するのに十分なほどスマートであり、プロパティが原因で新しいレンダリングパスを発生させないことで最適化できます。変更なし。

feature proposal team-Markup

最も参考になるコメント

これは非常に有効な懸念事項です。提起していただきありがとうございます。 フレームワークでのDPのスレッドアフィニティのサポートは大きな問題ではないかもしれませんが、INPCの実装者にとっては非常にうまくいく可能性があります。

一部のコードが非UIスレッドからプロパティの変更を発生させることができる場合は、プロパティのバッキングコードがバックグラウンドスレッドから変更される可能性があることも意味します。 ロックを使用して保護することもできますが、プロパティ変更チェーンがデッドロックになる可能性があるため、双方向バインディングが問題になる可能性があります。

INPCの最大の問題は、イベントが発生したときの「現在の」値の欠如です。 プロパティが適切に同期されていない状況(たとえば、 SelectedIndexItemsSourceが同期して更新されておらず、 SelectedIndexがその値を失っている)、またはプロパティの状態(TextBoxの変更や正規表現フィルターなど)。

これにより、コレクション全体を適切に保護する必要があるINCCに問題が発生します。 たとえば、移動されたアイテム、または移動されなくなったアイテムを参照するイベントを発生させることができます。

この問題の解決策がないと言っているわけではありませんが(確かにあります)、アフィニティの変更をスレッド化するIPNCリスナーは、インターフェイスの両端でこの問題を簡単にするのに十分ではありません。

全てのコメント3件

これは非常に有効な懸念事項です。提起していただきありがとうございます。 フレームワークでのDPのスレッドアフィニティのサポートは大きな問題ではないかもしれませんが、INPCの実装者にとっては非常にうまくいく可能性があります。

一部のコードが非UIスレッドからプロパティの変更を発生させることができる場合は、プロパティのバッキングコードがバックグラウンドスレッドから変更される可能性があることも意味します。 ロックを使用して保護することもできますが、プロパティ変更チェーンがデッドロックになる可能性があるため、双方向バインディングが問題になる可能性があります。

INPCの最大の問題は、イベントが発生したときの「現在の」値の欠如です。 プロパティが適切に同期されていない状況(たとえば、 SelectedIndexItemsSourceが同期して更新されておらず、 SelectedIndexがその値を失っている)、またはプロパティの状態(TextBoxの変更や正規表現フィルターなど)。

これにより、コレクション全体を適切に保護する必要があるINCCに問題が発生します。 たとえば、移動されたアイテム、または移動されなくなったアイテムを参照するイベントを発生させることができます。

この問題の解決策がないと言っているわけではありませんが(確かにあります)、アフィニティの変更をスレッド化するIPNCリスナーは、インターフェイスの両端でこの問題を簡単にするのに十分ではありません。

WPFはこれを理解しているので、おそらくそこからソリューションを引き出すだけですか?

素晴らしい提案。 これはCollectionChangedイベントに対して行います(多少偶然です...)。NotifyPropertyChangedに対しても同じことができるはずです。

このページは役に立ちましたか?
0 / 5 - 0 評価