3 回答

TA貢獻1848條經驗 獲得超10個贊
是否有處理此類問題的良好做法?
如果您希望兩個保存都發生,那么使用鎖(或SemaphoreSlim
)對它們進行序列化是一種方法。如果您想阻止第二次保存開始,那么通常的方法是在保存過程中禁用這些控件,例如,通過IsBusy
數據綁定到您的 UI 的屬性。
注意事項:
IsBusy
同步設置您的屬性。這會立即禁用控件。IsBusy
在 a中取消finally
設置,以確保它始終未設置,即使發生錯誤也是如此。

TA貢獻1804條經驗 獲得超7個贊
正如您所說,我還認為鎖是最好的方法。
我推薦使用 Stepehen Cleary straigthforward 解決方案:https ://github.com/StephenCleary/AsyncEx
因此,您的代碼看起來像
private readonly AsyncLock _lock = new AsyncLock();
private async void Save()
{
var id = Guid.NewGuid();
using (await _lock.LockAsync())
{
// It's safe to await while the lock is held
Debug.WriteLine($"Starting save {id}");
await Task.Delay(100); // Simulate slow task
Debug.WriteLine($"Finished save {id}");
}
}
這并不會真正影響代碼的可讀性,并且您最終會得到一個異步方法隊列。

TA貢獻1825條經驗 獲得超4個贊
這是 Rx 的絕佳樣本。如果你不想使用ReactiveUI(它可以很容易地與 MVVMLight 相鄰),你所需要的只是一個屬性改變的信號。
使用 RxUI:
this.WhenAnyValue(x => x.MyText, x => x.IsChecked) // this you will need to emulate if you don't want RxUI
.Throttle(TimeSpan.FromMilliseconds(150)) // wait for 150ms after last signal, if there isn't any, send your own further into pipeline
.Synchronize()
.Do(async _ => await Save()) // we have to await so that Synchronize can work
.Subscribe();
這將在最后一次 MyText 更改或 IsChecked 更改后等待 150 毫秒,然后執行一次保存。
此外,RxUI 有非常聰明的 ICommand 實現,它支持開箱即用的異步工作,包括在工作期間禁用命令。
- 3 回答
- 0 關注
- 148 瀏覽
添加回答
舉報