簡體   English   中英

MVVM和異步屬性

[英]MVVM and async properties

我有一個具有以下屬性的ViewModel

public Employee SelectedEmployee
        {
            get { return _selectedEmployee; }
            set
            {
                if (value == _selectedEmployee) return;
                _selectedEmployee = value;

                if (_selectedEmployee != null)
                {
                    StaffHolidaysViewModel.HolidayAllowance = _staffDataService.EmployeeHolidayAllowance(_selectedEmployee.Id);
                    FireEmployeeSelectedMessage(SelectedEmployee.Id);
                }

                RaisePropertyChanged();
                RaisePropertyChanged(nameof(Allowance));
                RaisePropertyChanged(nameof(Taken));
                RaisePropertyChanged(nameof(Remaining));
                RaisePropertyChanged(nameof(TotalAbsences));
                RaisePropertyChanged(nameof(TotalSick));
                RaisePropertyChanged(nameof(TotalNonSickAbsences));
                RaisePropertyChanged(nameof(SelectedEmployeeLeavingDate));
                UpdateCanExecuteChanged();
            }
        }

StaffHolidaysViewModel.HolidayAllowance = _staffDataService.EmployeeHolidayAllowance(_selectedEmployee.Id);

包含對我想進行異步處理的方法的調用。 我不知道該怎么做,因為SelectedEmployee是一個綁定屬性。

<ComboBox Name="StaffMembers" ItemsSource="{Binding FilteredEmployees}" SelectedItem="{Binding SelectedEmployee}" Width="200" BorderThickness="1" BorderBrush="DimGray">
                    <ComboBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}"/>
                        </DataTemplate>
                    </ComboBox.ItemTemplate>
                </ComboBox>

由於它是一個屬性,因此無法使其類型為Task<Employee>

異步綁定MVVM屬性的推薦方法是什么? 還是只是不可能?

從技術上講,讓屬性執行異步任務不是想法方法,因為它們需要返回值。

為什么? 讓我們從另一個角度來看它:

異步意味着UI線程將不會停止(UI在處理時不會掛起),而主處理線程將等待操作完成並獲得結果(考慮到您正在使用await )。

當您定義綁定時,UI直接依賴於使用await的數據的屬性,這意味着UI必須等待( async操作無法發生),因此無法使屬性async ,因此您不能使用await

我到目前為止一直使用的所有變通方法是:

  1. 有一個名為.Result的異步Task返回方法的屬性。 我已經嘗試過了,它實際上並沒有提供最好的輸出。
  2. 您可以使方法返回IAsyncOperation<>而不是Task<> 這將為您提供調用.GetResults()方法的優勢,該方法將為您提供結果,並且不會凍結UI線程。 有關更多信息,請參見此處 如果您沒有任何后處理結果提取操作要執行,請使用此選項。
  3. 最后,此選項是我最常用的選項,我創建了一個異步方法,返回Task<> 我在那里執行所有操作並驗證結果。 獲得所需結果后,只需更新屬性並調用RaisePropertyChanged 這樣,我也可以處理其他視圖處理或中間加載屏幕,而不必因無法停止處理線程而受到限制。

底線

使用我在上面定義的三種方法之一。 他們都很好。 以下是一些用例的要點,以獲取游戲的得分表服務器為例:

  1. 當您不想停止任何線程而只為該屬性定義數據源時,請使用IAsyncOperation<> 代碼處理不會停止,也不會等待過程獲取結果。 例如:您只是想獲取分數並顯示出來。
  2. 如果您希望代碼等待任務完成以對結果執行其他操作,請使用Task<>返回方法。 例如:計算分數后,您要將整數值轉換為百分比。
  3. 使用.Result但它對我從未奏效。

如果還有其他意見,請在評論中提及

包含對我想進行異步處理的方法的調用。

我有一篇關於異步MVVM數據綁定的文章。 從本質上講,我通常做的是建立一個數據綁定的Task -我稱之為NotifyTaskCompletion文章,縮短到NotifyTask在我更新的庫

您可以通過將StaffHolidaysViewModel.HolidayAllowance的類型從它的類型(我將其稱為THolidayAllowance )更改為NotifyTask<T>包裝器(例如, NotifyTask<THolidayAllowance> )來使用它。

然后,您可以同步設置它:

StaffHolidaysViewModel.HolidayAllowance = NotifyTask.Create(
    _staffDataService.EmployeeHolidayAllowanceAsync(_selectedEmployee.Id));

您在這里要做的是啟動 EmployeeHolidayAllowanceAsync ,然后用NotifyTask包裝其Task 這是同步完成的,因此可以在屬性設置器中執行此操作。

然后,您的數據綁定也需要更新。 NotifyTask<T>具有幾個可以使用的屬性 最明顯的是Result ,它將最終保存EmployeeHolidayAllowanceAsync的結果(它返回默認值,直到EmployeeHolidayAllowanceAsync完成)。 還有IsNotCompletedIsFaulted ,您將使用它們來向用戶指示數據尚未到達或存在一些錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM