web-dev-qa-db-fra.com

Comment utiliser BeginInvoke C #

Pourriez-vous m'expliquer ceci s'il vous plaît:

someformobj.BeginInvoke((Action)(() =>
{
    someformobj.listBox1.SelectedIndex = 0;
}));

Pourriez-vous me dire comment utiliser begininvoke exactement? Quel est le type Action? Pourquoi il y a des crochets blancs ()? Et qu'est-ce que cela signifie =>?

46
Mohammed Noureldin

Action est un type de délégué fourni par le framework .NET. Le Action pointe vers une méthode sans paramètre et ne renvoie pas de valeur.

() => Est la syntaxe expression lambda . Les expressions lambda ne sont pas de type Delegate. Invoke requiert Delegate afin que Action puisse être utilisé pour envelopper l'expression lambda et fournir le résultat attendu de Type à Invoke()

Invoke provoque l'exécution de Action sur le thread ayant créé le handle de fenêtre du contrôle. Changer de thread est souvent nécessaire pour éviter Exceptions. Par exemple, si on essaie de définir la propriété Rtf sur un RichTextBox lorsqu'un appel est nécessaire, sans appeler d'abord Invoke, une exception Cross-thread operation not valid Sera alors levée. Vérifiez Control.InvokeRequired Avant d'appeler Invoke.

BeginInvoke est la version asynchrone de Invoke. Asynchrone signifie que le thread ne bloquera pas l'appelant, contrairement à un appel synchrone bloquant.

74
P.Brian.Mackey

Je suppose que votre code concerne Windows Forms.
Vous appelez BeginInvoke si vous souhaitez que quelque chose soit exécuté de manière asynchrone dans le thread d'interface utilisateur: modifiez les propriétés du contrôle dans la plupart des cas.
En gros, ceci est accompli en passant le délégué à une procédure qui est exécutée périodiquement. (traitement de la boucle de message et ce genre de choses)

Si BeginInvoke est appelé pour Delegate, le délégué est simplement appelé de manière asynchrone.
(Invoke pour la version synchronisée.)

Si vous voulez plus de code universel qui fonctionne parfaitement pour WPF et WinForms, vous pouvez considérer Task Parallel Library et exécuter le Task avec l'accord avec context . (TaskScheduler.FromCurrentSynchronizationContext())

Et pour ajouter un peu à ce que d’autres ont déjà dit: Lambdas peut être traité comme une méthode anonyme ou expressions .
Et c’est pourquoi vous ne pouvez pas simplement utiliser var avec lambdas: le compilateur a besoin d’un indice.

UPDATE:

cela nécessite .Net v4.0 et supérieur

// This line must be called in UI thread to get correct scheduler
var scheduler = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext();

// this can be called anywhere
var task = new System.Threading.Tasks.Task( () => someformobj.listBox1.SelectedIndex = 0);

// also can be called anywhere. Task  will be scheduled for execution.
// And *IF I'm not mistaken* can be (or even will be executed synchronously)
// if this call is made from GUI thread. (to be checked) 
task.Start(scheduler);

Si vous avez démarré la tâche à partir d'un autre thread et que vous devez attendre son achèvement, task.Wait() bloquera l'appel du thread jusqu'à la fin de la tâche.

En savoir plus sur les tâches ici .

10
Pavel Voronin