Ich habe versucht, Async-Methoden zu lesen und versuche nun, meine eigene Async-Methode zu erstellen. Die Methode ist ein Webservice-Aufruf, der eine Liste von Fehlerprotokollen zurückgibt. Ich bin mir nicht sicher, ob ich es richtig verstanden habe, also dachte ich, ich würde meinen Code teilen, um zu sehen, ob ich etwas anderes machen sollte.
Ich möchte nur, dass der Code eine Liste von Fehlerprotokollen zurückgibt, indem er eine Methode GetAllErrorLogs () aufruft, die eine synchronisierte Methode ist. Da es eine Sekunde dauern kann, alle Fehlerprotokolle abzurufen, möchte ich die Möglichkeit haben, andere Sachen zu machen, nachdem ich die GetAllErrorLogs () Methode aufgerufen habe. Hier ist der Code.
%Vor%Danke!
Ich habe vor kurzem einen Vortrag bei ThatConference auf async
auf der Serverseite , und ich adressiere dieses Problem in den Folien.
Auf der Serverseite möchten Sie die Verwendung von Task.Run
und anderen Konstrukten vermeiden, die in der Warteschlange des Thread-Pools arbeiten. Halten Sie Threadpool-Threads so weit wie möglich für die Verarbeitung von Anforderungen bereit.
Im Idealfall würde Ihr Repository also eine asynchrone Methode GetAllErrorLogsAsync
haben, die selbst asynchron wäre. Wenn GetAllErrorLogs
nicht asynchron sein kann, können Sie es auch einfach direkt aufrufen (indem Sie await Task.Run
entfernen).
Da es eine Sekunde dauern kann, alle Fehlerprotokolle abzurufen, möchte ich die Möglichkeit haben, andere Sachen zu machen, nachdem ich die GetAllErrorLogs () Methode aufgerufen habe.
Wenn Sie GetAllErrorLogsAsync
verfügbar haben, können Sie dies einfach mit Task.WhenAll
tun. Wenn GetAllErrorLogs
jedoch synchron ist, können Sie dies nur tun, indem Sie in Ihrer Anfrage parallel arbeiten (z. B. mehrere Aufrufe von Task.Run
gefolgt von Task.WhenAll
).
Paralleler Code auf dem Server muss mit großer Beklemmung angegangen werden. Dies ist nur in sehr begrenzten Szenarien akzeptabel. Der gesamte Punkt von async
auf der Serverseite besteht darin, weniger Threads pro Anfrage zu verwenden, und wenn Sie mit der Parallelisierung beginnen, machen Sie das Gegenteil: mehrere Threads pro Anfrage . Dies ist nur sinnvoll, wenn Sie wissen, dass Ihre Benutzerbasis sehr klein ist. Andernfalls wird die Skalierbarkeit des Servers aufgehoben.
Ich fand diesen großartigen Artikel über den Codeprojekt ausführlich darüber, wie man das erreicht.
** Dies ist möglicherweise falsch, lesen Sie Kommentare oder Spinoff-Frage bei HttpContext.Current nach einer Wartezeit
Wenn ErrorLogRepository.GetAllErrorLogs()
nicht Thread-sicher ist, wird es seltsame Fehler und möglicherweise eine Ausnahme verursachen. Stellen Sie sicher, dass Ihr Code für Multithread-Operationen bereit ist, bevor Sie zu asynchronen Methoden wechseln. Dies ist offensichtlich eine sehr triviale Empfehlung, wird aber oft übersehen. Wenn Sie zum Beispiel HttpContext.Current
in Ihren Methoden referenzieren, wird Ihr Code in der asynchronen Methode und manchmal sogar NACH await
abstürzen. Der Grund dafür ist, dass der Code innerhalb des asynchronen Blocks möglicherweise in einem separaten Thread ausgeführt wird, der nicht auf dieselbe Eigenschaft HttpContext.Current
thread-static zugreifen kann, und await
wird in zwei Methoden kompiliert. Der gesamte Code vor einem await
wird in einem Thread ausgeführt und ruft dann den Code nach einem await-Schlüsselwort als Fortsetzung auf, möglicherweise aber auch in einem anderen Thread. Manchmal funktioniert Ihr Code sogar in einem asynchronen Block, nur um unerwartet zu ersticken, wenn er aus dem asynchronen Code herauskommt, was Sie für einen synchronen Teil Ihres Codes halten (aber in Wirklichkeit ist alles nach einem await
Schlüsselwort bereits geschehen nicht garantiert, der ursprüngliche Thread zu sein).
Tags und Links .net c# async-await