Warum gibt es keine Monitor.EnterAsync-ähnliche Methode?

8

Ich sehe viele Methoden im neuen Framework, die neue asynchrone Muster- / Sprachunterstützung für async/await in C # verwenden. Warum gibt es keinen Monitor.EnterAsync() oder anderen async lock Mechanismus, der den aktuellen Thread & amp; zurück, sobald lock verfügbar ist?

Ich gehe davon aus, dass dies nicht möglich ist - Frage warum?

    
pg0xC 15.03.2016, 18:15
quelle

4 Antworten

4

Einige Synchronisationselemente, die von .Net bereitgestellt werden, sind verwaltete Wrapper um die zugrunde liegenden systemeigenen Objekte.

Gegenwärtig gibt es keine systemeigenen Synchronisierungsprimitiven, die asynchrones Sperren implementieren. Also müssen die .Net-Implementierer das von Grund auf implementieren, was nicht so einfach ist, wie es scheint.

Außerdem bietet der Windows-Kernel keine Funktion von "locking-delegation", was bedeutet, dass Sie eine Sperre in einem Thread nicht sperren und die Eigentumsrechte an einen anderen Thread weitergeben können, was die Implementierung solcher Sperren extrem schwierig macht .

Meiner Meinung nach ist der dritte Grund philosophischer - wenn Sie nicht blockieren wollen - verwenden Sie nicht blockierende Techniken, wie die Verwendung von asynchronem IO, sperrfreien Algorithmen und Datenstrukturen. Wenn der Engpass Ihrer Anwendung durch starke Konflikte und den damit verbundenen Sperraufwand verursacht wird, können Sie Ihre Anwendung in anderer Form neu gestalten, ohne dass Sie asynchrone Sperren benötigen.

    
David Haim 15.03.2016, 18:47
quelle
4

Ich schätze, das Problem ist, dass der aktuelle Thread durch den Aufruf von Monitor.Enter die Sperre für das übergebene Objekt erhalten möchte. Sie sollten sich also fragen, wie Sie Monitor.EnterAsync implementieren würden? Der erste naive Versuch wäre:

%Vor%

Aber das tut offensichtlich nicht, was Sie erwarten, denn die Sperre würde durch den Thread, der für das neue Task gestartet wurde, und nicht durch den aufrufenden Thread gewonnen Sie würden jetzt einen Mechanismus benötigen, um sicherzustellen, dass Sie die Sperre nach dem Warten erhalten können. Aber ich kann mir derzeit keinen Weg vorstellen, wie ich sicherstellen kann, dass dies funktioniert und dass kein anderer Thread die Sperre dazwischen bekommt.

Das sind nur meine 2 Cent (hätte als Kommentar gepostet, wenn es nicht zu lang wäre). Ich freue mich auf eine mehr entzückende Antwort von jemandem mit detaillierteren Kenntnissen.

    
René Vogt 15.03.2016 18:35
quelle
2

Obwohl es in .NET standardmäßig keinen asynchronen Monitor gibt Stephen Cleary hat eine großartige Bibliothek < a href="https://github.com/StephenCleary/AsyncEx"> AsyncEx , das sich mit Synchronisierungsproblemen befasst, wenn async / await verwendet wird.

Es hat eine Klasse AsyncMonitor , die genau das tut, wonach Sie suchen. Sie erhalten es entweder von GitHub oder als NuGet-Paket .

Anwendungsbeispiel:

%Vor%     
Gediminas Masaitis 15.03.2016 18:52
quelle
2
  

Ich gehe davon aus, dass dies nicht möglich ist - Frage warum?

Es ist möglich, es wurde noch nicht gemacht.

Gegenwärtig ist das einzige async-kompatible Synchronisationsgrundelement in der BCL SemaphoreSlim , das als Semaphor oder einfache wechselseitige Ausschlusssperre fungieren kann.

Ich habe eine grundlegende AsyncMonitor , die ich geschrieben habe basierend auf Stephen Toubs Blogpost-Serie . Beachten Sie, dass die Semantik sich geringfügig von der BCL Monitor unterscheidet; insbesondere erlaubt es keine rekursiven Sperren (für Gründe, die ich in meinem Blog beschreibe >).

    
Stephen Cleary 16.03.2016 16:19
quelle

Tags und Links