577 votes

Quelle est la différence entre ManualResetEvent et AutoResetEvent dans .NET?

J'ai lu la documentation à ce sujet et je pense que je comprends. Un AutoResetEvent réinitialise lorsque le code passe par event.WaitOne() , mais pas ManualResetEvent .

Est-ce correct?

983voto

Dan Goldstein Points 8940

Oui. C’est comme la différence entre une porte et un poste de péage. Le ManualResetEvent est la porte qui doit être fermé (Réinitialiser). AutoResetEvent est un poste de péage, permettant à une voiture aller en fermant automatiquement avant celle qui suit peut passer à travers.

137voto

Michael Damatov Points 5453

Imaginez que le s’exécute et `` en une seule opération atomique.

62voto

Martin Brown Points 8593

La réponse courte est oui. La différence la plus importante est qu’un AutoResetEvent permettra seulement à un seul thread en attente de continuer. Un ManualResetEvent sera en revanche garder permettant discussions, plusieurs en même temps même, pour continuer jusqu'à ce que vous lui indiquiez d’arrêter (Réinitialiser).

21voto

Teoman shipahi Points 7988

J'ai créé des exemples simples pour clarifier la compréhension de ManualResetEvent vs AutoResetEvent.

AutoResetEvent: supposons que vous avez 3 travailleurs fil. Si l'un de ces threads appel WaitOne() tous les 2 autres threads d'arrêt d'exécution et d'attendre le signal. Je suis en supposant qu'ils sont à l'aide de WaitOne(). C'est comme, si je ne suis pas le travail, personne ne travaille. Dans le premier exemple, vous pouvez voir que

            autoReset.Set();
            Thread.Sleep(1000);
            autoReset.Set();

Lorsque vous appelez Set(); tous les threads de travail et d'attendre le signal. Après 1 seconde, je suis d'envoi de la deuxième signal et de leur exécution et attendre (WaitOne();). Que penser de ces gars-là sont les joueurs de l'équipe de football et, si un joueur dit je vais attendre jusqu'à ce que le gestionnaire m'appelle, et d'autres vont attendre jusqu'à ce que le gestionnaire de leur dit de continuer (Set();)

public class AutoResetEventSample
    {
        private AutoResetEvent autoReset = new AutoResetEvent(false);

        public void RunAll()
        {
            new Thread(Worker1).Start();
            new Thread(Worker2).Start();
            new Thread(Worker3).Start();
            autoReset.Set();
            Thread.Sleep(1000);
            autoReset.Set();
            Console.WriteLine("Main thread reached to end.");
        }

        public void Worker1()
        {
            Console.WriteLine("Entered in worker 1");
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker1 is running {0}", i);
                Thread.Sleep(2000);
                autoReset.WaitOne();
            }
        }
        public void Worker2()
        {
            Console.WriteLine("Entered in worker 2");

            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker2 is running {0}", i);
                Thread.Sleep(2000);
                autoReset.WaitOne();
            }
        }
        public void Worker3()
        {
            Console.WriteLine("Entered in worker 3");

            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker3 is running {0}", i);
                Thread.Sleep(2000);
                autoReset.WaitOne();
            }
        }
    }

Dans cet exemple, vous pouvez clairement voir que lors de la première hit Set(); il va laisser tous les threads, puis après 1 sec il signale tous les threads en attente! Dès que vous définissez de nouveau, peu importe qu'ils appellent WaitOne() à l'intérieur, ils vont continuer à courir parce que vous avez manuellement appel Reset() pour tous les arrêter.

            manualReset.Set();
            Thread.Sleep(1000);
            manualReset.Reset();
            Console.WriteLine("Press to release all threads.");
            Console.ReadLine();
            manualReset.Set();

Il s'agit plus d'Arbitre/les Joueurs de la relation il y a, indépendamment de tout joueur est blessé et attendre pour jouer à d'autres vont continuer à travailler. Si l'Arbitre dit d'attendre (Reset();) ensuite, tous les joueurs vont attendre jusqu'au prochain signal.

    public class ManualResetEventSample
    {
        private ManualResetEvent manualReset = new ManualResetEvent(false);

        public void RunAll()
        {
            new Thread(Worker1).Start();
            new Thread(Worker2).Start();
            new Thread(Worker3).Start();
            manualReset.Set();
            Thread.Sleep(1000);
            manualReset.Reset();
            Console.WriteLine("Press to release all threads.");
            Console.ReadLine();
            manualReset.Set();
            Console.WriteLine("Main thread reached to end.");
        }

        public void Worker1()
        {
            Console.WriteLine("Entered in worker 1");
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker1 is running {0}", i);
                Thread.Sleep(2000);
                manualReset.WaitOne();
            }
        }
        public void Worker2()
        {
            Console.WriteLine("Entered in worker 2");

            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker2 is running {0}", i);
                Thread.Sleep(2000);
                manualReset.WaitOne();
            }
        }
        public void Worker3()
        {
            Console.WriteLine("Entered in worker 3");

            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Worker3 is running {0}", i);
                Thread.Sleep(2000);
                manualReset.WaitOne();
            }
        }
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X