Quand utiliser TaskEx.C. TaskEx.RunEx
J'essaie de comprendre quand utiliser TaskEx.Run
. J'ai donné deux exemples de code que j'ai écrit ci-dessous qui produisent le même résultat. Ce que je n'arrive pas à voir, c'est pourquoi je voudrais prendre le de la Tâche.RunEx TaskEx.RunEx
approche, je suis sûr qu'il y a une bonne raison, et espérais que quelqu'un pourrait me renseigner.
async Task DoWork(CancellationToken cancelToken, IProgress<string> progress)
{
int i = 0;
TaskEx.RunEx(async () =>
{
while (!cancelToken.IsCancellationRequested)
{
progress.Report(i++.ToString());
await TaskEx.Delay(1, cancelToken);
}
}, cancelToken);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (button.Content.ToString() == "Start")
{
button.Content = "Stop";
cts.Dispose();
cts = new CancellationTokenSource();
listBox.Items.Clear();
IProgress<string> progress = new Progress<string>(s =>
{
listBox.Items.Add(s);
listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]);
});
DoWork(cts.Token, progress);
}
else
{
button.Content = "Start";
cts.Cancel();
}
}
Je peux obtenir les mêmes résultats comme
async Task DoWork(CancellationToken cancelToken)
{
int i = 0;
while (!cancelToken.IsCancellationRequested)
{
listBox.Items.Add(i++);
listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]);
await TaskEx.Delay(100, cancelToken);
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (button.Content.ToString() == "Start")
{
button.Content = "Stop";
cts.Dispose();
cts = new CancellationTokenSource();
listBox.Items.Clear();
DoWork(cts.Token);
}
else
{
button.Content = "Start";
cts.Cancel();
}
}
Le fil au-dessus est une discussion sur les raisons de TaskEx.RunEx, son tout à voir avec les changements qui ne pourrait pas être mis dans le cœur .NET fonctionnalité pour le CTP, mais sera intégré correctement pour la version finale
Changé
Changé
Task.RunEx
à TaskEx.RunEx
Il n'y a ni Run()
ni RunEx()
dans Async CTP Task
classe. Ils sont tous les deux dans TaskEx
. Corrigez-moi si je me trompeOriginalL'auteur poco | 2012-02-17
Vous devez vous connecter pour publier un commentaire.
Utilisation
TaskEx.Run
lorsque vous souhaitez exécuter du code synchrone dans un pool de threads contexte.Utilisation
TaskEx.RunEx
lorsque vous souhaitez exécuter du code asynchrone dans un pool de threads contexte.Stephen Toub a deux billets de blog liées à la différence de comportement:
Ce n'est qu'une des nombreuses options que vous avez pour création de tâches. Si vous n'avez pas à utiliser
Run
/RunEx
, alors vous ne devriez pas. Utilisation simpleasync
méthodes, et de n'utiliserRun
/RunEx
si vous avez besoin d'exécuter quelque chose dans le fond.Dans .Net 4.5 DP, il semble y avoir seulement
Task.Run()
, pas deEx
es.TaskEx est dans le CTP. Dans .Net 4.5 les méthodes sur TaskEx ont été intégrés dans la Tâche.
Dans .NET 4.5,
TaskEx.Run
devient une surcharge deTask.Run
, etTaskEx.RunEx
devient également une surcharge deTask.Run
.effectue un déballage de l'intérieur de la tâche. Si vous passez un lambda asynchrone à
Run
dans VS2010, travail "just fine" -- si vous ne se soucient pas quand il se termine. Toutefois, si vous souhaitez le retour de l'Task
à compléter lorsque le lambda asynchrone est terminée, puis utilisezTaskEx
. Voir ce post ou ce post pour plus d'info.OriginalL'auteur Stephen Cleary
La différence entre vos deux
DoWork()
méthodes est que la première (qui utiliseTaskEx.RunEx()
) n'est pas asynchrone à tous. Il exécute entièrement synchrone, commence l'autre tâche sur un autre thread, et renvoie immédiatement un formulaire deTask
. Si vousawait
ed ouWait()
ed sur cette tâche, il ne serait pas attendre jusqu'à ce que l'intérieur de la tâche est terminée.OriginalL'auteur svick
Tâche.Exécuter génère un nouveau thread dans la plupart des scénarios que je comprends.
Il est important de noter que, tout simplement, parce que vous marquez une méthode asynchrone, et l'utilisation awaiters, ce n'est PAS (forcément) dire que les nouveaux threads sont créés, les achèvements sont programmées le MÊME thread d'exécution qu'ils ont été appelés depuis dans de nombreux cas.
L'astuce ici a à voir avec la SchedulingContext. Si elle est définie pour un multithread appartement, alors vous allez déléguer les achèvements viables les threads du pool de threads. Si vous êtes dans un single thread apartment comme tous WPF et WinForms code de l'INTERFACE utilisateur, alors il sera de retour pour le thread appelant pour l'achèvement permettant le travail à faire directement sur l'INTERFACE, sans visible fil de l'ordonnancement dans le code.
Task.Run
files d'attente pour le pool de threads, ce qui n'est généralement pas démarrer un nouveau thread.await
les horaires de ses suites en cours deSynchronizationContext
ouTaskScheduler
(pas de fil) - voir à la fin de cet article qui s'applique encore que de la CTP v3 (et VS11 dev preview). Je couvre aussi async contexte dans mon async intro post. Ce contexte n'a rien à voir avec MTA ou des membres du personnel, s'il est possible d'avoir un contexte qui prend en charge STA ou MTA.Je suis agréablement corrigé 😀
OriginalL'auteur Firoso