Correggere l'opzione IsAsync non ha nulla a che fare con l'attività, dice semplicemente all'interfaccia utente di mostrare il valore di fallback e non di bloccare mentre viene eseguita la chiamata get.
Cosa può andare storto con il tuo codice. Hmmmmm penso che dovrei provare per capire se qualcosa è andato storto. Hai un numero di cose "cattive".
-
Codice nel costruttore. Mantieni il riferimento all'attività in modo che non sia tutto negativo, ma generalmente non dovresti avere un codice come questo in un costruttore
-
Chiamare .Result su un'attività. Questo può causare deadlock
-
Avere un'attività asincrona ma non in attesa.
-
Utilizzo di Task.Run all'interno di un'attività? Puoi semplicemente chiamare attendere Task.Delay direttamente
Ristrongrà il tuo codice come segue
ViewModel
public class ViewModel : INotifyPropertyChanged
{
private string name
public string Name {
get {return name;}
set {
name = value;
PropertyChanged("Name");
}
public ICommand GetNameAsync;
private void PropertyChanged(string prop)
{
if( PropertyChanged != null )
{
PropertyChanged(this, new PropertyChangedEventArgs(prop);
}
}
public ViewModel()
{
Name="Loading...";
GetNameAsync = new AsyncCommand(async () => {Name = await GetNameAsync()});
}
private async Task<string> GetNameAsync()
{
await nameService.getName();
}
}
XAML
<Window xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding GetNameAsync}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Label Content="{Binding Name}" />
</Window>
Ora il tuo Xaml chiamerà la funzione GetName quando la finestra verrà caricata, l'etichetta mostrerà "Caricamento in corso ..." fino a quando la funzione GetName non sarà completata, quando aggiornerà il nome
Sfortunatamente
-
WPF non ha un comando AsyncCommand.
Devi crearne uno tu o usarne uno da un framework di terze parti (vedi sotto)
-
INotifyPropertyChanged è una seccatura da digerire.
Raccomando di usare Fody con il suo plugin INotifyPropertyChanged
link
AsyncCommand
link
using System;
using System.Threading.Tasks;
using System.Windows.Input;
namespace OpenWeather.Command
{
internal class AsyncCommand : ICommand
{
private readonly Func<Task> _execute;
private readonly Func<bool> _canExecute;
private bool _isExecuting;
public AsyncCommand(Func<Task> execute) : this(execute, () => true)
{
}
public AsyncCommand(Func<Task> execute, Func<bool> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return !(_isExecuting && _canExecute());
}
public event EventHandler CanExecuteChanged;
public async void Execute(object parameter)
{
_isExecuting = true;
OnCanExecuteChanged();
try
{
await _execute();
}
finally
{
_isExecuting = false;
OnCanExecuteChanged();
}
}
protected virtual void OnCanExecuteChanged()
{
if (CanExecuteChanged != null) CanExecuteChanged(this, new EventArgs());
}
}
}