3 回答

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

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超7個(gè)贊
正如您所說,我還認(rèn)為鎖是最好的方法。
我推薦使用 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}");
}
}
這并不會真正影響代碼的可讀性,并且您最終會得到一個(gè)異步方法隊(duì)列。

TA貢獻(xiàn)1825條經(jīng)驗(yàn) 獲得超4個(gè)贊
這是 Rx 的絕佳樣本。如果你不想使用ReactiveUI(它可以很容易地與 MVVMLight 相鄰),你所需要的只是一個(gè)屬性改變的信號。
使用 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 毫秒,然后執(zhí)行一次保存。
此外,RxUI 有非常聰明的 ICommand 實(shí)現(xiàn),它支持開箱即用的異步工作,包括在工作期間禁用命令。
- 3 回答
- 0 關(guān)注
- 153 瀏覽
添加回答
舉報(bào)