Quelle est la différence entre Invoke() et BeginInvoke()

je me demande juste Quelle est la différence entre BeginInvoke() et Invoke() ?

principalement ce que chacun serait utilisé pour.

EDIT: Quelle est la différence entre créer un objet threading et appeler invoquer sur cela et juste appeler BeginInvoke() sur un délégué? ou sont-ils la même chose?

351
demandé sur DIF 2008-10-23 16:38:04

6 réponses

tu veux dire délégué.Invoquer / BeginInvoke ou contrôler.Invoke / BeginInvoke?

  • Delegate.Invoke: S'exécute de manière synchrone, sur le même thread.
  • délégué.BeginInvoke: S'exécute de manière asynchrone, sur un ThreadPool thread.
  • contrôle.Invoke: S'exécute sur le thread de L'interface utilisateur, mais calling thread attend son achèvement avant de continuer.
  • contrôle.BeginInvoke: exécute sur le thread de L'interface utilisateur, et appelle le thread n'attend pas d'être terminé.

la réponse de Tim mentionne quand vous voudrez peut - être utiliser BeginInvoke-même si elle était surtout orientée vers délégué.BeginInvoke, je suppose.

pour les applications Windows Forms, je suggère que vous devriez habituellement utiliser BeginInvoke. De cette façon, vous n'avez pas besoin de vous inquiéter de l'impasse, par exemple - mais vous devez comprendre que L'UI peut ne pas avoir été mis à jour au moment où vous prochain coup d'oeil! En particulier, vous ne devez pas modifier les données que le thread de L'interface utilisateur pourrait être sur le point d'utiliser à des fins d'affichage. Par exemple, si vous avez une personne avec les propriétés prénom et LastName, et que vous avez fait:

person.FirstName = "Kevin"; // person is a shared reference
person.LastName = "Spacey";
control.BeginInvoke(UpdateName);
person.FirstName = "Keyser";
person.LastName = "Soze";

alors L'interface utilisateur pourrait bien finir par afficher "Keyser Spacey". (Il y a une chance extérieure qu'il puisse afficher "Kevin Soze" mais seulement à travers la bizarrerie du modèle de mémoire.)

Sauf si vous avez ce genre de problème, cependant, Contrôle.BeginInvoke est plus facile à obtenir droite, et évitera votre fil d'arrière-plan d'avoir à attendre pour aucune bonne raison. Notez que L'équipe de Windows Forms a garanti que vous pouvez utiliser le contrôle.BeginInvoke de manière "feu et oubli", c'est-à-dire sans jamais appeler EndInvoke. Ce n'est pas le cas des appels asynchrones en général: normalement, chaque appel BeginXXX devrait avoir un appel EndXXX correspondant, généralement dans le callback.

511
répondu Jon Skeet 2009-12-23 21:34:19

en S'appuyant sur la réponse de Jon Skeet, il y a des moments où vous voulez invoquer un délégué et attendre que son exécution soit terminée avant que le fil courant ne continue. Dans ces cas, L'appel D'appel est ce que vous voulez.

dans les applications multi-threading, vous pouvez ne pas vouloir qu'un thread attende sur un délégué pour terminer l'exécution, surtout si ce délégué effectue des e/s (ce qui pourrait rendre le délégué et votre bloc de thread).

dans ces cas, le BeginInvoke serait utile. En l'appelant, vous dites au délégué de commencer, mais alors votre fil est libre de faire d'autres choses en parallèle avec le délégué.

L'utilisation de BeginInvoke augmente la complexité de votre code, mais il y a des moments où l'amélioration des performances en vaut la peine.

41
répondu Tim Stewart 2008-10-23 12:49:49

la différence entre Control.Invoke() et Control.BeginInvoke() est,

  • BeginInvoke() programmera l'action asynchrone sur le fil GUI. Quand l'action asynchrone est programmée, votre code continue. Quelque temps plus tard (vous ne savez pas exactement quand) votre action asynchrone sera exécutée
  • Invoke() exécutera votre action asynchrone (sur le thread GUI) et attendra que votre action soit terminée.

une conclusion logique est qu'un délégué que vous passez à Invoke() peut avoir des paramètres externes ou une valeur de retour, tandis qu'un délégué que vous passez à BeginInvoke() ne peut pas (vous devez utiliser EndInvoke pour récupérer les résultats).

21
répondu Sujit 2012-09-11 07:07:32

juste pour donner un exemple bref et fonctionnel pour voir un effet de leur différence

new Thread(foo).Start();

private void foo()
{
  this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
    (ThreadStart)delegate()
    {
        myTextBox.Text = "bing";
        Thread.Sleep(TimeSpan.FromSeconds(3));
    });
  MessageBox.Show("done");
}

Si l'utilisation BeginInvoke , MessageBox pop simultanément à la mise à jour. Si utiliser invoquer , MessageBox pops après les 3 secondes de sommeil. Par conséquent, en montrant l'effet d'un appel asynchrone ( BeginInvoke ) et d'un appel synchrone ( Invoke ).

14
répondu KMC 2012-12-14 05:11:39

délégué.BeginInvoke () asynchronously file l'appel d'un délégué et retourne le contrôle immédiatement. Lors de l'utilisation de Délégué.BeginInvoke (), vous devriez appeler Delegate.EndInvoke() dans la méthode de rappel pour obtenir les résultats.

délégué.Invoke () appelle le délégué de façon synchrone dans le même thread.

article MSDN

8
répondu Aaron Palmer 2008-10-23 13:11:34

j'ajoute juste pourquoi et quand utiliser Invoke ().

invoquez() et BeginInvoke() marshal le code que vous spécifiez au thread de dispatcher.

mais contrairement à BeginInvoke(), Invoke() bloque votre thread jusqu'à ce que le répartiteur exécute votre code. vous pourriez vouloir utiliser Invoke() si vous avez besoin de mettre en pause une opération asynchrone jusqu'à ce que l'utilisateur ait fourni une sorte de rétroaction.

Par exemple, vous pourriez call Invoke () pour exécuter un extrait de code qui affiche une boîte de dialogue OK/Cancel. Après que l'utilisateur clique sur un bouton et que votre code marshalé soit terminé, la méthode invoke() reviendra, et vous pouvez agir sur la réponse de l'utilisateur.

Voir Pro WPF en C# chapitre 31

6
répondu Ingako 2015-01-06 04:33:27