第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會有你想問的

如何從 ViewModel 正確執(zhí)行異步方法?

如何從 ViewModel 正確執(zhí)行異步方法?

C#
一只甜甜圈 2022-10-23 13:58:05
出于這個(gè)問題的目的,我有一個(gè)簡單Window的以下 XAML:<StackPanel>    <TextBox Text="{Binding MyText}" />    <CheckBox IsChecked="{Binding IsChecked}">Check</CheckBox></StackPanel>每當(dāng)用戶在TextBox或中輸入文本時(shí)CheckBox,我想執(zhí)行一個(gè)緩慢的任務(wù)(例如將模型的狀態(tài)保存到磁盤)。這是視圖模型:public class ViewModel : ViewModelBase  // using GalaSoft.MvvmLight{    private string _myText;    public string MyText    {        get => _myText;        set        {            if (Set(ref _myText, value))                Save();        }    }    private bool _isChecked;    public bool IsChecked    {        get => _isChecked;        set        {            if (Set(ref _isChecked, value))                Save();        }    }    private async void Save()    {        var id = Guid.NewGuid();        Debug.WriteLine($"Starting save {id}");        await Task.Delay(100);  // Simulate slow task        Debug.WriteLine($"Finished save {id}");    }}該Save方法模擬一個(gè)緩慢的任務(wù),例如保存到磁盤。出于調(diào)試目的,它會在執(zhí)行此操作之前和之后輸出一個(gè)唯一 ID。此外,該方法是異步的,因?yàn)槲也幌M?UI 在操作期間凍結(jié)。問題是,在用戶在 中鍵入內(nèi)容TextBox,然后檢查 后CheckBox,屬性會很快更新。這會導(dǎo)致以下調(diào)試示例輸出:Starting save 6ea6c102-cbe7-472f-b8b8-249499ff7f64Starting save c77b4478-14ca-4243-a45b-7b35b5663d49Finished save 6ea6c102-cbe7-472f-b8b8-249499ff7f64Finished save c77b4478-14ca-4243-a45b-7b35b5663d49如您所見,第一個(gè)保存操作(來自)在第二個(gè)保存操作(來自)開始MyText之前沒有完成。IsChecked這讓我有點(diǎn)害怕,因?yàn)槲蚁耄瑪?shù)據(jù)可能會以錯(cuò)誤的順序保存并損壞。是否有處理此類問題的良好做法?我想了幾個(gè)可能的解決方案。Delay=100首先是在TextBox綁定中使用類似的東西。這將導(dǎo)致在Save用戶停止輸入 100 毫秒后調(diào)用該方法。由于各種原因,這是一個(gè)丑陋的解決方案。第二種是使用SemaphoreSlim. 在Save方法內(nèi)部,我可以用try/將代碼括起來finally以使用此處所述的信號量。這實(shí)際上有效,但我不確定這是否是處理此問題的最佳方法。
查看完整描述

3 回答

?
慕桂英546537

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ò)誤也是如此。


查看完整回答
反對 回復(fù) 2022-10-23
?
三國紛爭

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ì)列。


查看完整回答
反對 回復(fù) 2022-10-23
?
鳳凰求蠱

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),它支持開箱即用的異步工作,包括在工作期間禁用命令。


查看完整回答
反對 回復(fù) 2022-10-23
  • 3 回答
  • 0 關(guān)注
  • 153 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號