Question

J'utilise un AutoResetEvent où plusieurs appels d'ensemble peuvent être faites sur un événement (gestion des exceptions). Il y a des moments où un jeu supplémentaire est appelé, donc lorsque le code fait un second appel sur un événement WaitOne, il passe juste à travers parce que la porte a déjà été ouverte.

La solution est d'appeler droite Remise à zéro avant la WaitOne. Y at-il une solution de nettoyage ou est-ce la seule façon de le faire? Exemple de code:

private void DoSomeWork()
{
    Thread thrd = new Thread(new ThreadStart(DoSomeOtherStuff));
    thrd.Start();

    //mEvt.Reset();
    mEvt.WaitOne();

    //continue with other stuff
}

private void DoSomeOtherStuff()
{
    /* lots of stuff */

    mEvt.Set();
}

private void ExceptionTriggerNeedsToBreakOutOfDoSomeWork()
{
   mEvt.Set();
}

Après l'exception est gérée, je dois appeler DoSomeWork à nouveau, mais depuis Set peut-être été appelé à plusieurs exceptions (ou exceptions relancée), le WaitOne coule juste à travers.

Ma solution est d'appeler toujours Remise à zéro avant la WaitOne. Est-ce la solution approriate, une mauvaise conception, ou est-il un autre type d'événement qui va gérer ce scénario?

EDIT:. Je viens d'emménager la réinitialisation commenté (solution proposée) à côté de l'événement

Était-ce utile?

La solution

Mon inquiétude serait que si vous appelez Reset () avant WaitOne (), vous êtes en difficulté si aucun Set () est toujours appelé. Cela peut se produire si vous appelez Set (), puis appuyez sur Reset () immédiatement après, avant de frapper WaitOne (). Même si vous appelez Set () deux fois, il n'y a aucune garantie que vous n'appelez Reset () après les deux, bloquer le thread sans mécanisme de libération.

Idéalement, vous auriez un bloc try..catch..finally et appeler l'ensemble () dans le bloc finally, et ne pas avoir votre propagation de manipulation d'exception à travers des méthodes. Est-ce que le travail pour vous?

Hans est exact que dans ce scénario, le multithreading est inutile. Mes préoccupations ne concernent que si vous êtes vraiment multithreading avec vos appels à WaitOne ().

Cela me préoccupe également que vous appelez ensemble plus d'une fois ... est-ce que cela veut dire que lorsque le premier ensemble est appelé, la ressource doit vraiment rester bloqué? Si vous êtes toujours en mesure de frapper Set () une deuxième fois, pour moi que vous dit que vous êtes toujours d'exécuter du code qui fonctionne avec des ressources partagées. Dans ce cas, vous ne voulez pas l'appel à WaitOne () à débloquer.

A noter également, du MSDN:

  

Il n'y a aucune garantie que chaque appel à la méthode Set publiera un fil. Si deux appels sont trop rapprochés, de sorte que le second appel se produit avant qu'un thread a été libéré, un seul thread est libéré. Il est comme si le second appel n'a pas eu lieu.

Dans tous les cas, il semble que votre code soit devrait emprunter la voie de lancer une exception, ou en cours d'exécution à la fin, mais pas les deux. C'EST À DIRE. vous ne devriez pas appellerez Set () deux fois.

Autres conseils

Ce n'est pas un vrai problème, le WaitOne () appel remet automatiquement l'événement. Après tout, vous avez utilisé un AutoResetEvent, pas ManualResetEvent. Phrase clé est ici Réinitialiser Auto.

En le voyant à la vapeur à travers l'appel WaitOne () est assez normal aussi. Vous avez une belle multiple core CPU, le fil a démarré tout de suite lorsque vous avez appelé Start () et n'a pas pris, mais quelques microsecondes pour faire le travail. Milliseconde, quelle que soit, plus vite que le clin d'œil.

Peut-être plus au point, tu ne pas besoin d'un fil ici. À partir d'un, puis d'attendre à la fin est inutile. Il suffit d'appeler le DoSomeOtherStuff () directement.

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