Question

Vous vous demandez simplement quelle est la différence entre BeginInvoke () et Invoke () ?

Principalement ce pour quoi chacun serait utilisé.

EDIT: Quelle est la différence entre la création d’un objet thread et l’appel d’appel sur cet élément et le simple appel de BeginInvoke () sur un délégué? ou sont-ils la même chose?

Était-ce utile?

La solution

Voulez-vous dire Delegate.Invoke / BeginInvoke ou Control.Invoke / BeginInvoke?

  • Delegate.Invoke: s'exécute de manière synchrone sur le même thread.
  • Delegate.BeginInvoke: s'exécute de manière asynchrone sur un thread de pool de threads.
  • Control.Invoke: s'exécute sur le thread d'interface utilisateur, mais le thread appelant est terminé avant de continuer.
  • Control.BeginInvoke: s'exécute sur le thread d'interface utilisateur et le thread d'appel n'attend pas son achèvement.

La réponse de Tim indique quand vous voudrez peut-être utiliser BeginInvoke - même si elle était principalement destinée à Delegate.BeginInvoke, je suppose.

Pour les applications Windows Forms, je suggère que vous utilisiez généralement BeginInvoke. Ainsi, vous n'avez pas besoin de vous inquiéter de l'impasse, par exemple, mais vous devez comprendre que l'interface utilisateur n'a peut-être pas été mise à jour avant la prochaine consultation! En particulier, vous ne devez pas modifier les données que le thread d'interface utilisateur est sur le point d'utiliser à des fins d'affichage. Par exemple, si vous avez une propriété Personne avec les propriétés Prénom et Nom, et que vous l’avez fait:

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

Dans ce cas, l’interface utilisateur pourrait bien afficher "Keyser Spacey". (Il y a une chance extérieure qu'il affiche "Kevin Soze" mais uniquement par l'étrangeté du modèle de mémoire.)

À moins que vous n'ayez ce genre de problème, Control.BeginInvoke est plus facile à résoudre et évite à votre thread d'arrière-plan d'attendre sans raison valable. Notez que l'équipe Windows Forms a garanti que vous pouvez utiliser Control.BeginInvoke dans un "feu et oublier". manière - c’est-à-dire sans jamais appeler EndInvoke. Ce n’est pas le cas des appels asynchrones en général: normalement chaque BeginXXX doit avoir un appel EndXXX correspondant, généralement dans le rappel.

Autres conseils

En s’inspirant de la réponse de Jon Skeet, vous voudrez peut-être appeler un délégué et attendre que son exécution soit terminée avant que le fil de discussion actuel ne continue. Dans ces cas, l'appel Invoke est ce que vous voulez.

Dans les applications multi-thread, vous ne souhaitez peut-être pas qu'un thread attende qu'un délégué termine son exécution, en particulier si ce délégué effectue des E / S (ce qui risquerait de bloquer le délégué et votre thread).

Dans ce cas, BeginInvoke serait utile. En l'appelant, vous dites au délégué de commencer mais votre thread 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 peut arriver que les performances améliorées valent la complexité.

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

  • BeginInvoke () planifiera l'action asynchrone sur le thread d'interface graphique. Une fois l'action asynchrone 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 d'interface graphique) 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 de sortie ou une valeur de retour, tandis qu'un délégué que vous passez à BeginInvoke () impossible (vous devez utiliser EndInvoke pour récupérer les résultats).

Juste pour donner un bref exemple de travail 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 vous utilisez BeginInvoke , MessageBox apparaît simultanément à la mise à jour du texte. Si vous utilisez Invoke , MessageBox apparaît après les 3 secondes de sommeil. Par conséquent, vous obtenez l'effet d'un appel asynchrone ( BeginInvoke ) et synchrone ( Invoke ).

Delegate.BeginInvoke () met en file d'attente de manière asynchrone l'appel d'un délégué et renvoie le contrôle immédiatement. Lorsque vous utilisez Delegate.BeginInvoke (), vous devez appeler Delegate.EndInvoke () dans la méthode de rappel pour obtenir les résultats.

Delegate.Invoke () appelle le délégué dans le même thread de manière synchrone.

Article MSDN

Ajoutez simplement pourquoi et quand utiliser Invoke ().

Invoke () et BeginInvoke () marshal le code que vous spécifiez pour le thread du distributeur.

Mais contrairement à BeginInvoke (), Invoke () bloque votre thread jusqu'à ce que le répartiteur exécute votre code. Vous pouvez utiliser Invoke () si vous devez suspendre une opération asynchrone jusqu'à ce que l'utilisateur fournisse une sorte de retour.

Par exemple, vous pouvez appeler Invoke () pour exécuter un extrait de code contenant une boîte de dialogue OK / Annuler. Une fois que l'utilisateur a cliqué sur un bouton et que votre code marshalé est terminé, la méthode invoke () est renvoyée et vous pouvez agir en fonction de la réponse de l'utilisateur.

Voir le chapitre 31 de WPF Pro en C #

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top