AsyncRelayCommand 和 AsyncRelayCommand<T>
和 AsyncRelayCommand
AsyncRelayCommand<T>
是一種 ICommand
實作,可擴充 所提供的 RelayCommand
功能,並支援異步操作。
平臺 API:
AsyncRelayCommand
、、AsyncRelayCommand<T>
RelayCommand
、IAsyncRelayCommand
、、IAsyncRelayCommand<T>
運作方式
AsyncRelayCommand
和 AsyncRelayCommand<T>
具有下列主要功能:
- 它們會擴充連結庫中所含同步命令的功能,並支援
Task
傳回委派。 - 它們可以使用其他
CancellationToken
參數包裝異步函式以支援取消,而且會公開CanBeCanceled
和IsCancellationRequested
屬性,以及Cancel
方法。 - 它們會公開
ExecutionTask
屬性,可用來監視暫止作業的進度,以及IsRunning
可用來檢查作業何時完成的 。 這特別適合將命令系結至UI元素,例如載入指標。 - 它們會實
IAsyncRelayCommand
作 和IAsyncRelayCommand<T>
介面,這表示 viewmodel 可以使用這些命令輕鬆地公開命令,以減少類型之間的緊密結合。 例如,這可讓您更輕鬆地將命令取代為視需要公開相同公用 API 介面的自定義實作。
使用異步命令
讓我們想像一個類似範例中所述 RelayCommand
的案例,但執行異步操作的命令:
public class MyViewModel : ObservableObject
{
public MyViewModel()
{
DownloadTextCommand = new AsyncRelayCommand(DownloadText);
}
public IAsyncRelayCommand DownloadTextCommand { get; }
private Task<string> DownloadText()
{
return WebService.LoadMyTextAsync();
}
}
使用相關的 UI 程式代碼:
<Page
x:Class="MyApp.Views.MyPage"
xmlns:viewModels="using:MyApp.ViewModels"
xmlns:converters="using:Microsoft.Toolkit.Uwp.UI.Converters">
<Page.DataContext>
<viewModels:MyViewModel x:Name="ViewModel"/>
</Page.DataContext>
<Page.Resources>
<converters:TaskResultConverter x:Key="TaskResultConverter"/>
</Page.Resources>
<StackPanel Spacing="8" xml:space="default">
<TextBlock>
<Run Text="Task status:"/>
<Run Text="{x:Bind ViewModel.DownloadTextCommand.ExecutionTask.Status, Mode=OneWay}"/>
<LineBreak/>
<Run Text="Result:"/>
<Run Text="{x:Bind ViewModel.DownloadTextCommand.ExecutionTask, Converter={StaticResource TaskResultConverter}, Mode=OneWay}"/>
</TextBlock>
<Button
Content="Click me!"
Command="{x:Bind ViewModel.DownloadTextCommand}"/>
<ProgressRing
HorizontalAlignment="Left"
IsActive="{x:Bind ViewModel.DownloadTextCommand.IsRunning, Mode=OneWay}"/>
</StackPanel>
</Page>
按兩下Button
時,會叫用 命令,並更新 。ExecutionTask
作業完成時,屬性會引發通知,通知會反映在UI中。 在此情況下,會顯示工作狀態和目前工作的結果。 請注意,若要顯示工作的結果,必須使用 TaskExtensions.GetResultOrDefault
方法 - 這可讓您存取尚未完成且未封鎖線程的工作結果(並可能導致死結)。