Dans .NET, dans quel thread les événements seront-ils traités?

J’ai essayé d’implémenter un modèle producteur / consommateur dans c #. J’ai un thread consommateur qui surveille une queue partagée et un thread producteur qui place des éléments dans la queue partagée. Le thread producteur est abonné pour recevoir des données, c’est-à-dire qu’il possède un gestionnaire d’événement et qu’il rest assis et attend qu’un événement OnData se déclenche (les données sont envoyées à partir d’une API tierce). Quand il obtient les données, il les met dans la queue pour que le consommateur puisse les gérer.

Lorsque l’événement OnData se déclenche dans le producteur, je m’attendais à ce qu’il soit traité par mon thread producteur. Mais cela ne semble pas être ce qui se passe. L’événement OnData semble être manipulé sur un nouveau thread à la place! Est-ce que .net fonctionne toujours … les événements sont traités sur leur propre thread? Puis-je contrôler quel thread va gérer les événements lorsqu’ils sont déclenchés? Que se passe-t-il si des centaines d’événements sont soulevés presque simultanément … chacun aurait-il son propre fil?

Après avoir relu la question, je pense comprendre le problème maintenant. Vous avez essentiellement quelque chose comme ça:

 class Producer { public Producer(ExternalSource src) { src.OnData += externalSource_OnData; } private void externalSource_OnData(object sender, ExternalSourceDataEventArgs e) { // put e.Data onto the queue } } 

Et puis, vous avez un fil de discussion qui tire les choses de cette queue. Le problème est que l’événement OnData est déclenché par votre object ExternalSource , quel que soit le thread sur lequel il s’exécute.

Les event C # sont fondamentalement un simple ensemble de delegates faciles à utiliser et le “déclenchement” d’un événement amène le runtime à parcourir tous les delegates et à les déclencher un par un.

Ainsi, votre gestionnaire d’événements OnData est appelé sur le thread sur lequel s’exécute ExternalSource .

À moins de faire le marshaling vous-même, un événement sera exécuté sur le thread qui l’invoque; Il n’y a rien de particulier dans la façon dont les événements sont invoqués, et votre thread producteur n’a pas de gestionnaire d’événement, votre thread producteur a simplement dit “hé, lorsque vous déclenchez cet événement, appelez cette fonction”. Il n’y a rien là qui provoque l’exécution de l’événement sur le thread attaché, ni sur son propre thread (sauf si vous BeginInvoke plutôt que d’appeler le délégué de l’événement normalement, mais cela l’exécutera simplement sur le ThreadPool ).

Élever un événement avec Invoke revient à appeler une méthode – il s’exécute dans le même thread que vous l’avez généré.

Élever un événement avec BeginInvoke utilise ThreadPool . Voici quelques détails mineurs

Vous devez utiliser les gestionnaires de révisions automatiques pour ce problème ….. dans autoresetevent, lorsque le producteur le produit, réglez le signal puis le consommateur réinitialise son signal et consum .. après avoir consommé consumz le signal, alors seul le producteur produit …

 AutoResetEvent pro = new AutoResetEvent(false); AutoResetEvent con = new AutoResetEvent(true); public void produser() { while(true) { con.WaitOne(); pro.Set(); } } public void consumer() { while (true) { pro.WaitOne(); .................**** con.Set(); } } private void button1_Click(object sender, EventArgs e) { Thread th1 = new Thread(produser); th1.Start(); Thread th2 = new Thread(consumer); th2.Start(); }