UI以外のスレッドからの通知変更を発生させるプロパティからUIバインディングが発生することを許可します
プロパティをバインドするときは、常にUIスレッドでプロパティ変更通知を発生させる必要があります。そうしないと、実行時例外が発生します。 これにより、UIがビューモデルとモデルにブリードし、適切なスレッドでレイズできるようになります。これにより、.NET標準ライブラリからINPCを使用できなくなります(ベイトアンドスイッチを使用する場合を除く)。 。
さらに、1つのフレーム中にプロパティが複数回変更される可能性があるため、実際に必要な回数よりも多くの回数UIスレッドにジャンプする可能性があります(必要なのは、プロパティに「ダーティ」のフラグを付けて、次のレンダリングパス。
これにより、コードが大幅に複雑になり、エラーが発生しやすくなります。
また、WinUI 3.0でも問題が発生します。これは、レガシーUWPスレッドとWinUIスレッドの2つのUIスレッドがあるためです。どちらを上げる必要がありますか?
糸脱毛の懸念はもちろん有効ですが、これが最終的には本当に問題になるとは思いません。 UIが更新される前に複数のINPCイベントが発生することは問題ではありません。これは、最後のイベントのみが問題になるためです。 これは、UIスレッドに複数回切り替える既存のコードと同じです。 最初のスレッドがUIスレッドに切り替わると、プロパティはすでに何度も更新されている可能性があるため、最後の1つが勝ちです。
当然、値が読み取られるときにダーティフラグが設定されないようにする短いロックが必要になるため、プロパティが読み取られると同時にプロパティが更新された場合は、次のフレームで2回目のUI更新が行われます。
実際、たとえば値がfalseからtrueに変更され、falseに戻る場合、Dependencyプロパティは、値が変更されていないことを検出するのに十分なほどスマートであり、プロパティが原因で新しいレンダリングパスを発生させないことで最適化できます。変更なし。
これは非常に有効な懸念事項です。提起していただきありがとうございます。 フレームワークでのDPのスレッドアフィニティのサポートは大きな問題ではないかもしれませんが、INPCの実装者にとっては非常にうまくいく可能性があります。
一部のコードが非UIスレッドからプロパティの変更を発生させることができる場合は、プロパティのバッキングコードがバックグラウンドスレッドから変更される可能性があることも意味します。 ロックを使用して保護することもできますが、プロパティ変更チェーンがデッドロックになる可能性があるため、双方向バインディングが問題になる可能性があります。
INPCの最大の問題は、イベントが発生したときの「現在の」値の欠如です。 プロパティが適切に同期されていない状況(たとえば、 SelectedIndex
とItemsSource
が同期して更新されておらず、 SelectedIndex
がその値を失っている)、またはプロパティの状態(TextBoxの変更や正規表現フィルターなど)。
これにより、コレクション全体を適切に保護する必要があるINCCに問題が発生します。 たとえば、移動されたアイテム、または移動されなくなったアイテムを参照するイベントを発生させることができます。
この問題の解決策がないと言っているわけではありませんが(確かにあります)、アフィニティの変更をスレッド化するIPNCリスナーは、インターフェイスの両端でこの問題を簡単にするのに十分ではありません。
WPFはこれを理解しているので、おそらくそこからソリューションを引き出すだけですか?
素晴らしい提案。 これはCollectionChangedイベントに対して行います(多少偶然です...)。NotifyPropertyChangedに対しても同じことができるはずです。
最も参考になるコメント
これは非常に有効な懸念事項です。提起していただきありがとうございます。 フレームワークでのDPのスレッドアフィニティのサポートは大きな問題ではないかもしれませんが、INPCの実装者にとっては非常にうまくいく可能性があります。
一部のコードが非UIスレッドからプロパティの変更を発生させることができる場合は、プロパティのバッキングコードがバックグラウンドスレッドから変更される可能性があることも意味します。 ロックを使用して保護することもできますが、プロパティ変更チェーンがデッドロックになる可能性があるため、双方向バインディングが問題になる可能性があります。
INPCの最大の問題は、イベントが発生したときの「現在の」値の欠如です。 プロパティが適切に同期されていない状況(たとえば、
SelectedIndex
とItemsSource
が同期して更新されておらず、SelectedIndex
がその値を失っている)、またはプロパティの状態(TextBoxの変更や正規表現フィルターなど)。これにより、コレクション全体を適切に保護する必要があるINCCに問題が発生します。 たとえば、移動されたアイテム、または移動されなくなったアイテムを参照するイベントを発生させることができます。
この問題の解決策がないと言っているわけではありませんが(確かにあります)、アフィニティの変更をスレッド化するIPNCリスナーは、インターフェイスの両端でこの問題を簡単にするのに十分ではありません。