Je pense que mon exemple ci-dessous peut suivre l'approche de @Stephen-Cleary mais je voulais donner un exemple codé. Il est destiné à être utilisé dans un contexte de liaison de données, par exemple Xamarin.
Le constructeur de la classe - ou bien le setter d'une autre propriété dont elle dépend - peut appeler un void asynchrone qui remplira la propriété à la fin de la tâche sans avoir besoin d'un await ou d'un bloc. Lorsqu'il obtiendra finalement une valeur, il mettra à jour votre interface utilisateur via le mécanisme NotifyPropertyChanged.
Je ne suis pas certain qu'il y ait des effets secondaires à appeler un void aysnc depuis un constructeur. Peut-être qu'un commentateur pourra élaborer sur la gestion des erreurs, etc.
class MainPageViewModel : INotifyPropertyChanged
{
IEnumerable myList;
public event PropertyChangedEventHandler PropertyChanged;
public MainPageViewModel()
{
MyAsyncMethod()
}
public IEnumerable MyList
{
set
{
if (myList != value)
{
myList = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("MyList"));
}
}
}
get
{
return myList;
}
}
async void MyAsyncMethod()
{
MyList = await DoSomethingAsync();
}
}
4 votes
Ma question serait de savoir pourquoi. Une propriété est censée imiter quelque chose comme un champ en ce sens qu'elle doit généralement effectuer peu de travail (ou du moins très rapidement). Si vous avez une propriété de longue durée, il vaut mieux l'écrire comme une méthode pour que l'appelant sache qu'il s'agit d'un travail plus complexe.
0 votes
@James : C'est exactement ça - et je soupçonne que c'est la raison pour laquelle cela n'a pas été explicitement pris en charge dans le CTP. Ceci étant dit, vous pouvez toujours rendre la propriété de type
Task<T>
qui retournera immédiatement, aura une sémantique de propriété normale, et permettra toujours de traiter les choses de manière asynchrone si nécessaire.19 votes
James Mon besoin découle de l'utilisation de Mvvm et de Silverlight. Je veux pouvoir me lier à une propriété, où le chargement des données se fait paresseusement. La classe d'extension ComboBox que j'utilise exige que la liaison se fasse à l'étape InitializeComponent(), mais le chargement réel des données se fait beaucoup plus tard. En essayant d'accomplir avec aussi peu de code que possible, getter et async semble être la combinaison parfaite.
0 votes
Liés : stackoverflow.com/a/33942013/11635
0 votes
James et Reed, vous semblez oublier qu'il y a toujours des cas limites. Dans le cas de WCF, je voulais vérifier que les données placées sur une propriété sont correctes et cela devait être vérifié en utilisant le cryptage/décryptage. Les fonctions que j'utilise pour le décryptage emploient une fonction asynchrone d'un fournisseur tiers. (JE NE PEUX PAS FAIRE GRAND CHOSE ICI).
0 votes
@RashadRivera cela fait un moment que je n'ai pas utilisé WCF ou Silverlight, mais ils ne supportent pas la liaison aux propriétés asynchrones qui renvoient
Task<T>
?0 votes
Voici un exemple simple qui explique pourquoi quelqu'un pourrait appeler une méthode asynchrone dans une propriété. Dans Xamarin Essentials, pour renvoyer une valeur de SecureStorage, vous devez utiliser GetAsync. Cette valeur peut ensuite être liée à XAML via un modèle de vue. La propriété du modèle de vue doit donc faire cet appel au stockage sécurisé.
0 votes
Je sais que votre exemple renvoie un Enumerable, mais si votre méthode asynchrone ne renvoie qu'une Task, vous pourriez la changer pour renvoyer void et l'appeler depuis le setter.