次のようなメソッドがある UI コードがあります。
private async Task UpdateStatusAsync()
{
//Do stuff on UI thread...
var result = await Task.Run(DoBunchOfStuffInBackground);
//Update UI based on result of background processing...
}
目標は、プロパティがその状態に影響を与えるように変更されるたびに、UI が比較的複雑な計算されたステータスを更新することです。ここにはいくつかの問題があります。
- ステータスを更新する各場所からこのメソッドを直接呼び出すと、最終的に更新されたステータスが正しくない可能性があります。プロパティ A が変更され、次にプロパティ B が変更されたとします。B は A の後に UpdateStatusAsync を呼び出しますが、コールバック コード (最終的な UI の更新) が逆の順序で発生することがあります。つまり、(A -> 更新) -> (B -> 更新) -> (B 更新) -> (A 更新)。これは、最終的な UI が古いステータスを示していることを意味します (A を反映していますが、B は反映していません)。
- 以前の UpdateStatusAsync が最初に完了するのを常に待っていると (現在行っていること)、高価な状態計算を何度も実行することになります。理想的には、一連の更新の「最後の」計算のみを行う必要があります。
私が探しているのは、次のことを実現するクリーンなパターンです。
- 最終ステータスが「古い」状態であってはなりません (つまり、UI が基になる状態と同期しなくなることは望ましくありません)。
- 短時間に複数の更新呼び出しが発生した場合 (一般的なユース ケース)、重複した作業を避け、代わりに常に「最新の」更新を計算することをお勧めします。
- 複数の更新が非常に近い間隔で (つまり、ミリ秒以内に) 発生する場合があるため、他の更新要求が来た場合に備えて、処理を短時間開始しないようにする方法があると便利です。
これはかなり一般的な問題のように思われるので、これを行うための特にクリーンな方法を誰かが知っているかどうかここで尋ねたいと思いました。