Thread-sichere Cache-Bibliotheken für .NET

Hintergrund:

Ich verwalte mehrere Winforms-Apps und Klassenbibliotheken, die entweder vom Caching profitieren könnten oder es bereits tun. Mir ist auch bewusst, dassAnwendungsblock zwischenspeichern und dasSystem.Web.Caching Namespace (der, soweit ich weiß, außerhalb von ASP.NET verwendet werden kann).

Ich habe festgestellt, dass beide oben genannten Klassen zwar in dem Sinne, dass einzelne Methoden synchronisiert sind, technisch "threadsicher" sind, sie jedoch nicht besonders gut für Multithread-Szenarien geeignet zu sein scheinen. Insbesondere implementieren sie keinGetOrAdd Methode ähnlich wie in der neuenConcurrentDictionary Klasse in .NET 4.0.

Ich betrachte eine solche Methode alsPrimitive für die Caching- / Lookup-Funktionalität, und offensichtlich haben die Framework-Designer dies auch erkannt - deshalb sind die Methoden in den gleichzeitigen Auflistungen vorhanden. Abgesehen von der Tatsache, dass ich .NET 4.0 noch nicht in Produktions-Apps verwende, ist ein Wörterbuch kein vollwertiger Cache - es verfügt nicht über Funktionen wie Ablauf, persistenter / verteilter Speicher usw.

Warum ist das wichtig:

Ein recht typisches Design in einer "Rich Client" -App (oder sogar einigen Web-Apps) besteht darin, beim Start der App einen Cache vorzuladen und zu blockieren, wenn der Client noch nicht geladene Daten anfordert (um sie anschließend für die Zukunft zwischenzuspeichern) verwenden). Wenn der Benutzer seinen Workflow schnell durchläuft oder wenn die Netzwerkverbindung langsam ist, ist es nicht ungewöhnlich, dass der Client mit dem Preloader konkurriert, und es macht wirklich wenig Sinn, dieselben Daten zweimal anzufordern , vor allem wenn die Anfrage relativ teuer ist.

Ich habe also anscheinend ein paar ebenso schlechte Möglichkeiten:

Versuchen Sie nicht, die Operation atomar zu machen, und riskieren Sie, dass die Daten zweimal geladen werden (und möglicherweise zwei verschiedene Threads, die auf verschiedenen Kopien arbeiten).

Serialisieren Sie den Zugriff auf den Cache, dh sperren Sie den Cachegesamter Cache nur um aeinzelnes Objekt;

Fangen Sie an, das Rad neu zu erfinden, nur um ein paar zusätzliche Methoden zu erhalten.

Erläuterung: Beispiel Timeline

Angenommen, beim Start einer App müssen 3 Datensätze geladen werden. Das Laden dauert jeweils 10 Sekunden. Betrachten Sie die folgenden zwei Zeitleisten:

00:00 - Start loading Dataset 1
00:10 - Start loading Dataset 2
00:19 - User asks for Dataset 2

In dem obigen Fall muss der Benutzer, wenn wir keine Synchronisierung verwenden, volle 10 Sekunden auf Daten warten, die in 1 Sekunde verfügbar sind, da der Code erkennt, dass das Element noch nicht in den Cache geladen wurde und versuche es neu zu laden.

00:00 - Start loading Dataset 1
00:10 - Start loading Dataset 2
00:11 - User asks for Dataset 1

In diesem Fall fragt der Benutzer nach bereits vorhandenen Datenim der Cache. Wenn wir jedoch den Zugriff auf den Cache serialisieren, muss er ohne Grund weitere 9 Sekunden warten, da der Cache-Manager (was auch immer das ist) keine Kenntnis von dem hatspezifisches Element Nachgefragt wird nur, dass "etwas" angefordert wird und "etwas" in Bearbeitung ist.

Die Frage:

Gibt es Caching-Bibliotheken für .NET (vor 4.0), diemachen solche atomaren Operationen zu implementieren, wie man es von einem thread-sicheren Cache erwarten kann?

Oder gibt es alternativ eine Möglichkeit, einen vorhandenen "thread-sicheren" Cache zu erweitern, um solche Operationen zu unterstützen?ohne Serialisierung des Zugriffs auf den Cache (was den Zweck der Verwendung einer thread-sicheren Implementierung in erster Linie zunichte machen würde)? Ich bezweifle, dass es das gibt, aber vielleicht bin ich nur müde und ignoriere eine offensichtliche Problemumgehung.

Oder ... fehlt mir noch etwas? Ist es üblich, dass sich zwei konkurrierende Threads gegenseitig austoben, wenn beide zum ersten Mal oder nach Ablauf derselben Zeit denselben Gegenstand anfordern?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage