Wäre das nicht übertrieben und nur einer davon notwendig? Ich habe gesucht und gefunden verschiedene Beiträge über gegenseitige Ausgrenzung und sperrt in C # hier und hier .
Beispiel:
In unserer App haben wir eine Funktion, die mehrere Reconnection-Threads abspinnt. Innerhalb dieses Threads verwenden wir Mutex
und lock
. Würde nicht lock
den Zugriff auf diesen Codeabschnitt blockieren und verhindern, dass connect
von einem anderen Thread aktualisiert wird?
Weitere Informationen:
Dies ist in einem ASP.NET WebService, der nicht in einem Web Garden ausgeführt wird.
Dieser Mutex (weil er einen Namen hat) stoppt jeden Prozess auf demselben Computer, der darauf zugreift, während die Sperre nur andere Threads im selben Prozess stoppt. Ich kann nicht anhand dieses Codebeispiels sehen, warum Sie beide Arten von Sperren benötigen. Es scheint eine gute Übung zu sein, die einfache Sperre für eine kurze Zeit zu halten - aber dann ist der viel schwerere Interprozess-Mutex für eine wahrscheinlich längere (wenn auch überlappende) Periode gesperrt! Wäre einfacher, einfach den Mutex zu verwenden. Und vielleicht um herauszufinden, ob eine Interprozesssperre wirklich notwendig ist.
Übrigens ist catch {}
in diesem Szenario absolut falsch. Sie sollten finally { /* release mutex */ }
verwenden. Sie sind sehr verschieden. Der Catch schluckt weit mehr Arten von Ausnahme als es sollte, und verursacht auch verschachtelte schließlich Handler als Reaktion auf Low-Level-Ausnahmen wie Speicherbeschädigung, Zugriffsverletzung, usw. Also statt:
Sie sollten:
%Vor%Und wenn es bestimmte Ausnahmen gibt, von denen Sie wiederherstellen können, könnten Sie sie abfangen:
%Vor%"lock" ist im Grunde nur eine syntaktische Zucker für Montor.Enter / Exit. Mutex ist eine Mehrfachprozesssperre.
Sie haben ein sehr unterschiedliches Verhalten. Es ist nichts falsch daran, beide in der gleichen Anwendung oder den gleichen Methoden zu verwenden, da sie dazu gedacht sind, verschiedene Dinge zu blockieren.
Aber in Ihrem Fall denke ich, dass Sie besser in Semaphore und Monitor schauen können. Es klingt nicht so, als müssten Sie Prozesse blockieren, daher sind sie in dieser Situation wahrscheinlich die bessere Wahl.
Wie andere darauf hingewiesen haben, sperrt der Mutex alle Prozesse und die lokale Sperre (Monitor) sperrt nur die Threads, die dem aktuellen Prozess gehören. Jedoch ...
Der Code, den du gezeigt hast, hat einen ziemlich ernsten Fehler. Offenbar geben Sie den Mutex am Ende bedingungslos frei (d. H.% Co_de%), aber der Mutex wird nur übernommen, wenn reconnectMutex.ReleaseMutex()
site.ContainsKey()
zurückgibt.
Wenn also true
site.ContainsKey
zurückgibt, wird das Freigeben des Mutex false
auslösen, weil der aufrufende Thread nicht den Mutex besitzt.
Sie haben nicht genug Informationen gegeben, um das wirklich zu beantworten. Wie bereits von Earwicker angegeben, ermöglicht Ihnen ein Mutex eine Synchronisation über Prozesse hinweg. Wenn Sie also zwei Instanzen derselben App ausführen, können Sie den Zugriff serialisieren. Dies können Sie beispielsweise bei Verwendung externer Ressourcen tun.
Jetzt sperren Sie Site vor Sites vor Zugriff durch andere Threads in demselben Prozess. Dies kann abhängig davon sein, was andere Methoden / Threads tun. Nun, wenn dies der einzige Ort ist, an dem die Site gesperrt wird, dann denke ich, dass es Overkill ist.