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 ...;
});
}