Infrequent hängt in einer C # -Konsolenanwendung mit mehreren Threads, wenn Console.Writeline () oder Console.Write () verwendet wird.

8

Ich habe eine Konsolenanwendung geschrieben, die console.write und console.writeline für die Protokollierung verwendet. Die Anwendung ist eine Serveranwendung, die asynchrone beginacceptconnection () und startread () (Sockets) für die Kommunikation verwendet. Gelegentlich bekomme ich Berichte darüber, dass es hängen bleibt und von dem begrenzten Debugging kann ich sehen, dass das Problem Console.Writeline () oder Console.write () ist.

Da es sich um ein Multi-Threading handelt, habe ich auf die Protokollierungsklasse geachtet, sodass nur ein Thread gleichzeitig eine Nachricht protokollieren kann ... Wenn ich einen Hang gefangen habe, werden nur Threads blockiert und VS berichten, dass das Steuerelement in Console.Write übergeben wurde und es darauf wartet, dass es zurückkommt .... es tut es nie.

Vor ein paar Tagen habe ich einen weiteren Fehlerbericht bekommen, aber diesmal während des Bootup .... wo noch keine asynch Verbindungen gestartet wurden (der Haupt Thread erzeugt einen Thread zum Booten) und mir wurde ein Bild ..... siehe unten. (Ich habe die Anfang und Ende kritischen Abschnitt Linien hinzugefügt, um dies zu verhindern und es nicht)

%Vor%

Mein Lesen der MSDN schlägt vor, dass Console.WriteLine und Console.Write threadsafe sind und ich daher eigentlich keine Sperre brauche .... ich kann es auch nicht glauben, dass der Code von Microsoft falsch ist (;-) und also vermute ich, dass es eine Interaktion ist, die mein Code macht, die den Fehler erzeugt.

Nun meine Frage: Sollte ich etwas tun, um zu verhindern, dass Console.WriteLine und Console.Write unterbrochen werden? ... es ist meine Vermutung, dass etwas es unterbricht ... aber das weiß ich nicht wirklich !!

Jede Hilfe würde mir sehr gefallen.

Grüße,

Gordon.

    
Gordon Roxburgh 27.06.2011, 20:45
quelle

5 Antworten

8

Ich hatte das gleiche Problem.

Ich habe console.readkey() im Haupt-Thread verwendet, um das Schließen der Anwendung im Debug-Modus zu verhindern.

Nachdem ich es durch eine Endlosschleife ersetzt hatte, war mein Problem gelöst.

    
mostafa bafandegan 11.09.2012 13:52
quelle
2

Consol.Writeline() ist Thread-sicher. Also

  

Ich war vorsichtig, um die Protokollierungsklasse zu sperren

Dies sollte nicht notwendig sein und könnte sehr wohl der Fall von Deadlocks sein. Ohne Code-Beispiele ist es unmöglich zu sagen, ob / wie / was.

  

und so vermute ich, dass es eine Interaktion ist, die mein Code macht, die den Fehler erzeugt.

Sehr wahrscheinlich.

  

es ist meine Vermutung, dass etwas es unterbricht ..

Nein.

    
Henk Holterman 27.06.2011 20:50
quelle
2

Sie sollten Ihr Problem lösen, indem Sie die Sperren um die Protokollierung entfernen. Die Protokollierung erfolgt über Console.WriteLine , das synchronisiert (und threadsicher) ist. Sie verursachen möglicherweise einen Deadlock durch Ihren eigenen Sperrmechanismus (obwohl ich das nicht überprüfen kann, ohne den Code zu sehen).

    
Ethan Cabiac 27.06.2011 20:52
quelle
2

Das ist ein bisschen weit hergeholt, aber ich frage mich, ob Sie Console.WriteLine mit Objekten aufrufen, deren ToString () -Methode eine Sperre übernimmt. Wenn dies der Fall ist, können Sie sich in eine Deadlock-Situation bezüglich der Sperre begeben, die intern von Console.WriteLine vorgenommen wurde.

Ich habe einmal diesen Fehlerbericht an Microsoft Connect, obwohl sie es leider nicht beheben konnten.

    
Corey Kosak 27.06.2011 22:17
quelle
1

Ich nehme an, Ihre Anwendung wird von einem anderen Prozess gestartet, der stderr und stdout umleitet. Wenn Ihr "Watcher" -Verfahren ReadToEnd () für beide Streams verwendet der gleiche Thread, den Sie blockieren können.

Eine weitere Möglichkeit zum Deadlock besteht darin, die Eingabe des untergeordneten Prozesses über stdin zu senden, die wiederum einen anderen Prozess startet, der über eine Konsole verfügt, die unbegrenzt auf Eingaben wartet. Das ist mir einmal mit wmic.exe passiert, das blockiert wenn stdin umgeleitet wird.

Wenn Sie mit Ihrer Log-Klasse gespielt haben, vermute ich, dass Sie den zugrunde liegenden Stream von Console.Out mit Ihrem eigenen ändern. Bitte posten Sie mindestens den Callstack, wo Ihre Anwendung hängt, damit wir etwas analysieren können. Es gibt viele Möglichkeiten, sich in den Fuß zu schießen, wenn Sie den Konsolen-Stream durch Ihren eigenen ersetzen.

Mit freundlichen Grüßen   Alois Kraus

    
Alois Kraus 27.06.2011 20:53
quelle