Existe-t-il un moyen «standard» de spécifier qu'une continuation de tâche doit s'exécuter sur le thread à partir duquel la tâche initiale a été créée?
Actuellement, j'ai le code ci-dessous - cela fonctionne, mais garder une trace du répartiteur et créer une deuxième action semble être une surcharge inutile.
dispatcher = Dispatcher.CurrentDispatcher;
Task task = Task.Factory.StartNew(() =>
{
DoLongRunningWork();
});
Task UITask= task.ContinueWith(() =>
{
dispatcher.Invoke(new Action(() =>
{
this.TextBlock1.Text = "Complete";
}
});
Control.Invoke(Action)
, par exemple.TextBlock1.Invoke
plutôt quedispatcher.Invoke
Réponses:
Appelez la suite avec
TaskScheduler.FromCurrentSynchronizationContext()
:Cela ne convient que si le contexte d'exécution actuel se trouve sur le thread d'interface utilisateur.
la source
await
est un bon modèle - mais seulement si vous êtes dans unasync
contexte (comme une méthode déclaréeasync
). Sinon, il est toujours nécessaire de faire quelque chose comme cette réponse.Avec async, vous faites simplement:
Toutefois:
la source
false
version me confond. Je pensaisfalse
que cela pouvait continuer sur un autre thread.async
méthode (ce qui est nécessaire, à utiliserawait
). Quelle est la réponse quandawait
n'est pas disponible?Si vous avez une valeur de retour que vous devez envoyer à l'interface utilisateur, vous pouvez utiliser la version générique comme ceci:
Ceci est appelé à partir d'un ViewModel MVVM dans mon cas.
la source
Je voulais juste ajouter cette version car c'est un fil tellement utile et je pense que c'est une implémentation très simple. J'ai utilisé cela plusieurs fois dans différents types si l'application multithread:
la source
TaskScheduler
fait partie de BCL,Dispatcher
n'est pas le cas) et peut être utilisé pour composer des chaînes de tâches complexes car il ne doit pas se soucier d'opérations asynchrones de type "ignorer et oublier" (commeBeginInvoke
).Je suis arrivé ici via Google parce que je cherchais un bon moyen de faire des choses sur le thread d'interface utilisateur après avoir été à l'intérieur d'un appel Task.Run - En utilisant le code suivant, vous pouvez utiliser
await
pour revenir au thread d'interface utilisateur.J'espère que ça aidera quelqu'un.
Usage:
la source
static
le coursUI
.