[.net] Warum behebt Thread.Sleep (0) meine Probleme und wie vermeidet man sie?



Answers

Dies ist unmöglich zu beantworten, ohne die gesamte Codebasis zu betrachten.

Thread.Sleep ist eine schreckliche Praxis, und Sie sollten es nicht tun. Sie verschieben im Prinzip das Timing Ihres Codes, der zum Deadlock führt, anstatt die Deadlock-Bedingung von vornherein zu beheben.

Der Grund dafür, dass das Debuggen das Problem nicht anzeigt, besteht darin, dass beim Stoppen des Debuggers alle Threads in Ihrem Code angehalten werden, sodass auch das Timing der Ausführung Ihres Programms verschoben wird.

Was Sie hier tun möchten, ist hier Logging-Code einzufügen, um den Pfad der Ausführung Ihres Codes auf verschiedenen Threads zu verfolgen und basierend darauf den Deadlock zu bestimmen.

Question

Ich arbeite an einer Client-Server-Anwendung. Zu bestimmten Zeiten, auf bestimmten Rechnern, wenn mehr als 5 Clients Daten anfordern, scheint es zu einem Deadlock zu kommen. Wenn ich eintrete, um das Problem zu debuggen, scheint das Programm verarbeitet zu werden. Wenn Sie einfach einen Haltepunkt setzen, von dem ich weiß, dass das Programm gerade ausgeführt wird, und ihn einige Male auf den Haltepunkt drücken, wird er beendet. Wenn ich Thread.Sleep (0) an bestimmten Punkten im Code einfüge, meistens um einige CPU-intensive Schleifen, scheint es das Problem ziemlich vollständig zu lösen. Das einzige Problem, das ich jetzt habe, ist, dass, wenn ich Thread.Sleep (0) zu viel rufe, es den Code verlangsamen kann. Wenn ich es nicht genug nenne, scheint der Code im Stillstand zu sein. Ich kann zwar feststellen, dass es sich nicht um einen Deadlock handelt, denn wenn ich in den Code eintrete, verschwindet das Problem einfach, weil ich einen Thread pausiere.

Gibt es einen guten Weg, genau herauszufinden, was das verursacht? Es scheint, dass es nur auf meinem Laptop geschieht, auf dem Vista läuft, aber nicht auf meinem Desktop, auf dem Windows XP läuft. Es ist jedoch unmöglich zu debuggen, da das Problem einfach weggeht, wenn man einfach in den Code hineingeht. Ich habe Kommentare gelesen, dass das Aufrufen von Thread.Sleep (0) eine schlechte Übung ist und nicht notwendig sein sollte, und ich mag es nicht, Hexerei-Code in meine Anwendungen zu packen, den ich nicht verstehe, warum er da sein muss . Alle Hinweise würden sehr geschätzt werden.

[EDIT] Ich kann auch verifizieren, dass der Code immer noch läuft, wenn er "festgefahren" ist, denn wenn ich ihn lange genug belasse, wird er enden, nur die Menge an Zeit ist um viele Größenordnungen höher. Ich meine, es ist tatsächlich mindestens 100 mal langsamer, wenn es in diesem "Deadlock" -Modus ist. Die CPU ist auf 80-95% eingestellt, also funktioniert es, obwohl das, was es tut, über mich hinausgeht, weil es ewig dauert, um die Aufgabe zu erledigen.

[Weitere Informationen] Nur weil alle hier darauf bestehen, dass es sich um einen Deadlock handelt, habe ich den gesamten Code entfernt, der gesperrt wurde. Es gab nur ein paar Codezeilen, die irgendwie blockierten. Die Fäden arbeiten größtenteils völlig unabhängig voneinander, so dass es nicht viel Arbeit war, die Verriegelung vollständig zu entfernen. Das Problem besteht jedoch weiterhin. Es gibt keine synclocks mehr in meinem Code, keine Mutex mehr Sachen, die ich sehe, die einen Deadlock verursachen würden, aber das Problem ist immer noch da. Und es ist nicht festgefahren. Es läuft, wenn auch sehr langsam, obwohl es alle Prozessorressourcen verbraucht.




Ja, Sie haben möglicherweise eine Scheduler-Überlastung festgestellt.

Ich hoffe es nicht.




Wenn die Hardware Sie nicht zwingt, sollten Sie niemals sleep () verwenden.

Versuchen Sie, auf andere Weise über das Problem nachzudenken. Berücksichtigen Sie, welche Daten zwischen den Threads geteilt werden müssen, und überlegen Sie, wie Sie die Daten (IE, kopieren) an die Beteiligten senden können, anstatt den Zugriff zu teilen. Wenn Sie dies richtig machen, benötigen Sie möglicherweise keine Mutexe.

Denken Sie daran, lokale Variablen existieren auf verschiedenen Stapeln, aber Statik innerhalb von Funktionen sind im Wesentlichen globale Variablen (und natürlich müssen Sie Ihre Globalen genau betrachten).




Ich denke, es ist Zeit für dich, vom Computer wegzugehen und bis zum Whiteboard zu gehen. Analysieren Sie, wie jedes Element blockiert und unter welchen Bedingungen es das Schloss vorsichtig freigibt. Fünf Threads könnten ein schwieriges Problem sein, also vielleicht sehen, ob nur zwei Threads die gleiche Bedingung verursachen können. Etwas schließt nicht richtig und Sie müssen wo finden.

Es sei denn, dein Code ist nicht so viel Mühe wert, dann lass die Thread.sleep () da drin, weil es deine Leistung im großen Schema der Dinge nicht wirklich schadet.




Wie viele simultane Threads laufen gerade, wenn sie blockiert sind? Wenn Sie zu viele Threads haben, könnte die CPU die ganze Zeit damit verbringen, Kontextwechsel durchzuführen. Plus, Sie würden durch 1 MB Speicher pro Thread kauen.




Links