Condividi tramite


AsyncRelayCommand e AsyncRelayCommand<T>

e AsyncRelayCommand AsyncRelayCommand<T> sono ICommand implementazioni che estendono le funzionalità offerte da RelayCommand, con supporto per le operazioni asincrone.

API della piattaforma: AsyncRelayCommand, AsyncRelayCommand<T>, RelayCommand, IAsyncRelayCommand, IAsyncRelayCommand<T>

Come funzionano

AsyncRelayCommand e AsyncRelayCommand<T> hanno le funzionalità principali seguenti:

  • Estendono le funzionalità dei comandi sincroni inclusi nella libreria, con il supporto per Taski delegati che restituiscono.
  • Possono eseguire il wrapping di funzioni asincrone con un parametro aggiuntivo CancellationToken per supportare l'annullamento ed espongono proprietà CanBeCanceled e IsCancellationRequested nonché un Cancel metodo.
  • Espongono una ExecutionTask proprietà che può essere usata per monitorare lo stato di avanzamento di un'operazione in sospeso e un oggetto IsRunning che può essere usato per verificare il completamento di un'operazione. Ciò è particolarmente utile per associare un comando agli elementi dell'interfaccia utente, ad esempio gli indicatori di caricamento.
  • Implementano le IAsyncRelayCommand interfacce e IAsyncRelayCommand<T> , il che significa che il modello di visualizzazione può esporre facilmente i comandi usando questi per ridurre l'accoppiamento stretto tra i tipi. Ad esempio, ciò semplifica la sostituzione di un comando con un'implementazione personalizzata che espone la stessa superficie API pubblica, se necessario.

Uso di comandi asincroni

Si immagini uno scenario simile a quello descritto nell'esempio RelayCommand , ma un comando che esegue un'operazione asincrona:

public class MyViewModel : ObservableObject
{
    public MyViewModel()
    {
        DownloadTextCommand = new AsyncRelayCommand(DownloadText);
    }

    public IAsyncRelayCommand DownloadTextCommand { get; }

    private Task<string> DownloadText()
    {
        return WebService.LoadMyTextAsync();
    }
}

Con il codice dell'interfaccia utente correlato:

<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>

Quando si fa clic su Button, viene richiamato il comando e l'oggetto ExecutionTask aggiornato. Al termine dell'operazione, la proprietà genera una notifica che si riflette nell'interfaccia utente. In questo caso, vengono visualizzati sia lo stato dell'attività che il risultato corrente dell'attività. Si noti che per visualizzare il risultato dell'attività, è necessario usare il TaskExtensions.GetResultOrDefault metodo . In questo modo viene fornito l'accesso al risultato di un'attività che non è ancora stata completata senza bloccare il thread (ed eventualmente causando un deadlock).

Esempi