Utiliser async / attendre avec le répartiteur.BeginInvoke()
j'ai une méthode avec un code qui fait un await fonctionnement:
public async Task DoSomething()
{
var x = await ...;
}
j'ai besoin de ce code pour fonctionner sur le fil du répartiteur. Maintenant,Dispatcher.BeginInvoke() est awaitable, mais je ne peux pas marquer le lambda async pour exécuter le await à partir de l'intérieur, comme ceci:
public async Task DoSomething()
{
App.Current.Dispatcher.BeginInvoke(async () =>
{
var x = await ...;
}
);
}
À l'intérieur async, j'obtiens l'erreur:
ne peut pas convertir l'expression lambda en système de type'.Délégué ' parce que ce n'est pas un délégué type.
Comment puis-je travailler avec async de l'intérieur Dispatcher.BeginInvoke()?
2 réponses
réponse peut avoir introduit un bug obscur. Ce code:
public async Task DoSomething()
{
App.Current.Dispatcher.Invoke(async () =>
{
var x = await ...;
});
}
utilise Dispatcher.Invoke(Action callback) outrepasser la forme de Dispatcher.Invoke, qui accepte un async void lambda dans ce cas particulier. Cela peut conduire à un comportement tout à fait inattendu, comme cela se produit habituellement avec async void méthode.
Vous êtes probablement à la recherche de quelque chose comme ceci:
public async Task<int> DoSomethingWithUIAsync()
{
await Task.Delay(100);
this.Title = "Hello!";
return 42;
}
public async Task DoSomething()
{
var x = await Application.Current.Dispatcher.Invoke<Task<int>>(
DoSomethingWithUIAsync);
Debug.Print(x.ToString()); // prints 42
}
Dans ce cas, Dispatch.Invoke<Task<int>> accepte un Func<Task<int>> argument et renvoie la correspondante Task<int> qui est awaitable. Si vous n'avez pas besoin renvoyer rien DoSomethingWithUIAsync, il suffit d'utiliser Task au lieu de Task<int>.
alternativement, utilisez un des Dispatcher.InvokeAsync méthodes.
Utiliser Dispatcher.Invoke()
public async Task DoSomething()
{
App.Current.Dispatcher.Invoke(async () =>
{
var x = await ...;
});
}