1) Normalement, vous souhaitez retourner un Task
. La principale exception doit être quand vous avez besoin d'avoir un void
type de retour (pour les événements). Si il n'y a pas de raison de refuser d'avoir l'appelant await
votre tâche, pourquoi refuser?
2) async
des méthodes qui renvoient void
sont spéciale d'un autre aspect: ils représentent de haut niveau des opérations asynchrones, et ont des règles supplémentaires qui entrent en jeu lors de votre tâche renvoie une exception. La façon la plus simple est de montrer la différence est avec un exemple:
static async void f()
{
await h();
}
static async Task g()
{
await h();
}
static async Task h()
{
throw new NotImplementedException();
}
private void button1_Click(object sender, EventArgs e)
{
f();
}
private void button2_Click(object sender, EventArgs e)
{
g();
}
private void button3_Click(object sender, EventArgs e)
{
GC.Collect();
}
f
s'exception est toujours "observé". Une exception qui laisse un haut niveau de méthode asynchrone est simplement traité comme n'importe quel autre exception non gérée. g
s'exception n'est jamais observée. Lorsque le garbage collector vient de nettoyer la tâche, il voit que la tâche a entraîné dans une exception, et personne ne gérée à l'exception. Lorsque cela se produit, TaskScheduler.UnobservedTaskException
gestionnaire s'exécute. Vous ne devez jamais laisser cela se produire. Pour utiliser votre exemple,
public static async void AsyncMethod2(int num)
{
await Task.Factory.StartNew(() => Thread.Sleep(num));
}
Oui, utilisez async
et await
d'ici, ils assurez-vous que votre méthode fonctionne toujours correctement si une exception est levée.
pour plus d'informations, voir: http://msdn.microsoft.com/en-us/magazine/jj991977.aspx