Frage

Ich verwende eine Autoreset wo mehrere Set Anrufe können auf ein Ereignis (Exception Handling) erfolgen. Es gibt Zeiten, in denen ein extra Set genannt wird, also wenn der Code einen zweiten Anruf auf einem WaitOne Ereignisse macht, es geht gerade richtig durch, weil das Tor bereits geöffnet wurde.

Die Lösung ist Reset-Recht vor dem WaitOne zu nennen. Gibt es eine sauberere Lösung oder ist dies der einzige Weg, es zu tun? Beispielcode:

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();
}

Nachdem die Ausnahme behandelt wird, muss ich wieder DoSomeWork nennen, aber da Set kann in mehreren Ausnahmen (oder erneut ausgelöst Ausnahmen), die WaitOne nur durch Ströme genannt wurden.

Meine Lösung ist immer zurücksetzen aufrufen, bevor der WaitOne. Ist das die Lösung approriate, schlechtes Design, oder gibt es eine andere Art von Veranstaltung, die dieses Szenario behandelt?

EDIT:. Ich ziehe den kommentierten Reset (vorgeschlagene Lösung) neben dem Ereignis

War es hilfreich?

Lösung

Meine Sorge wäre, dass, wenn Sie Zurücksetzen () aufrufen, bevor WaitOne (), Sie sind in Schwierigkeiten, wenn kein Set () aufgerufen wird je. Dies könnte passieren, wenn Sie Set () aufrufen, dann drücken Sie Reset () unmittelbar danach vor WaitOne schlagen (). Selbst wenn Sie anrufen Set () zweimal, gibt es keine Garantie Sie nicht zurücksetzen rufen werden (), nachdem beide, den Faden ohne Mechanismus für die Freigabe blockiert.

Im Idealfall würden Sie eine try..catch..finally blockieren, und rufen Sie die Set () in der finally-Block, und nicht verteilt über Methoden haben Ihre Ausnahmebehandlung. Funktioniert das für Sie?

Hans ist richtig, dass in diesem Szenario das Multithreading nicht notwendig ist. Meine Bedenken gelten nur, wenn Sie wirklich mit Ihren Anrufen auf WaitOne sind Multithreading ().

Es geht mir auch, dass Sie Satz mehr sind Aufruf als einmal ... heißt das, dass, wenn der erste Satz genannt wird, soll die Ressource wirklich verriegelt bleiben? Wenn Sie noch in der Lage Set () ein zweites Mal zu schlagen, mir das sagt ich ist immer noch Ausführung von Code, dass die Arbeiten mit gemeinsam genutzten Ressourcen. In diesem Fall möchten Sie nicht den Anruf zu WaitOne () zu entsperren.

Beachten Sie auch, von der MSDN:

  

Es gibt keine Garantie, dass jeder Aufruf der Set-Methode einen Thread freigeben wird. Wenn zwei Anrufe zu dicht beieinander sind, so dass der zweite Anruf erfolgt, bevor ein Thread freigegeben wurde, nur ein Thread freigegeben wird. Es ist, als ob der zweite Anruf ist nicht geschehen.

Auf jedem Fall scheint es, wie Ihr Code sollte entweder die Strecke wirft eine Ausnahme gehen, oder zum Abschluss laufen, aber nicht beide. I.E. Sie sollten nicht zweimal anrufen Set ().

Andere Tipps

Dies ist kein wirkliches Problem, das WaitOne () aufrufen, das Ereignis automatisch zurücksetzt. Immerhin verwendete man eine Autoreset, kein Manual. Schlüsselwort hier ist Auto-Reset.

Sehen sie direkt durch die WaitOne () -Aufruf Dämpfen ist auch ziemlich normal. Sie haben einen schönen Multi-Core-CPU bekommen, wurde der Thread sofort gestartet, wenn Sie auf Start () aufgerufen und nicht nehmen, aber ein paar Mikrosekunden die Arbeit zu erledigen. Millisekunden, was auch immer, schneller als das Blinzeln des Auges.

Vielleicht mehr auf den Punkt, brauchen Sie nur nicht über einen hier Faden. beginnend, dann es bis zum Ende warten, ist sinnlos. Rufen Sie einfach die DoSomeOtherStuff () direkt an.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top