Training
Module
Implement Asynchronous Tasks - Training
Learn how to implement asynchronous tasks in C# apps using the `async` and `await` keywords and how to run asynchronous tasks in parallel.
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The AsyncRelayCommand
and AsyncRelayCommand<T>
are ICommand
implementations that extend the functionalities offered by RelayCommand
, with support for asynchronous operations.
Platform APIs:
AsyncRelayCommand
,AsyncRelayCommand<T>
,RelayCommand
,IAsyncRelayCommand
,IAsyncRelayCommand<T>
AsyncRelayCommand
and AsyncRelayCommand<T>
have the following main features:
Task
-returning delegates.CancellationToken
parameter to support cancelation, and they expose a CanBeCanceled
and IsCancellationRequested
properties, as well as a Cancel
method.ExecutionTask
property that can be used to monitor the progress of a pending operation, and an IsRunning
that can be used to check when an operation completes. This is particularly useful to bind a command to UI elements such as loading indicators.IAsyncRelayCommand
and IAsyncRelayCommand<T>
interfaces, which means that viewmodel can easily expose commands using these to reduce the tight coupling between types. For instance, this makes it easier to replace a command with a custom implementation exposing the same public API surface, if needed.Let's imagine a scenario similar to the one described in the RelayCommand
sample, but a command executing an asynchronous operation:
public class MyViewModel : ObservableObject
{
public MyViewModel()
{
DownloadTextCommand = new AsyncRelayCommand(DownloadText);
}
public IAsyncRelayCommand DownloadTextCommand { get; }
private Task<string> DownloadText()
{
return WebService.LoadMyTextAsync();
}
}
With the related UI code:
<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>
Upon clicking the Button
, the command is invoked, and the ExecutionTask
updated. When the operation completes, the property raises a notification which is reflected in the UI. In this case, both the task status and the current result of the task are displayed. Note that to show the result of the task, it is necessary to use the TaskExtensions.GetResultOrDefault
method - this provides access to the result of a task that has not yet completed without blocking the thread (and possibly causing a deadlock).
MVVM Toolkit feedback
MVVM Toolkit is an open source project. Select a link to provide feedback:
Training
Module
Implement Asynchronous Tasks - Training
Learn how to implement asynchronous tasks in C# apps using the `async` and `await` keywords and how to run asynchronous tasks in parallel.