Wie man lesen / generieren + Datei in thread-sicherer Weise in C # lesen

8

Ich verwende .NET Framework v4.5 .

Ich erstelle eine Art Bildresizer mit der MagickImage-Bibliothek.

Anwendungsfall:

Der Benutzer lädt ein großes Bild (4k * 4k Pixel) hoch und verwendet es an verschiedenen Orten mit unterschiedlicher Größe (200 * 200 Pixel, 1200 * 1200 Pixel).

Also erzeuge ich solche Bilder bei Bedarf, indem ich die Größe einer großen verändere und sie auf der Platte ablege.

Fall mit Nebenläufigkeit: Nutzer lädt ein Bild hoch, und dann fordern einige Nutzer das Thumbnail dieses Bilds an. In diesem Moment beginnt jede Benutzeranforderung mit der Erstellung von Miniaturansichten in der Größe, weil sie noch nicht existiert. Wenn der erste Thread, der die Größenänderung abgeschlossen hat, speichert es auf der Festplatte. Alle anderen Threads erhalten eine Ausnahme, weil die Datei bereits verwendet wird.

Vor diesem war es mit einem einzelnen Thread und es gab keine Notwendigkeit für eine Thread-Sicherheit.

Aber jetzt wird es in einem webbasierten Projekt verwendet und gleichzeitige Anfragen sind ebenfalls möglich .

Die aktuelle Implementierung sieht folgendermaßen aus:

%Vor%

Der einfachste Weg besteht darin, diese Operation zu sperren, aber in diesem Fall skaliert Resizer nur ein Bild in einem einzigen Zeitraum.

Eine andere Variante, die ich sehe, ist, etwas wie einen Sperrmechanismus zu erstellen, der mit einem String-Schlüssel gesperrt wird.

Aber irgendwie sehe ich ein Problem mit der doppelten Überprüfung, ob die Datei nach der Freigabe wie folgt existiert:

%Vor%

Gibt es einen guten Weg oder sogar einen .NET-Mechanismus, um so etwas ohne Overhead zu machen?

    
Dmitry Zaets 12.02.2015, 14:06
quelle

1 Antwort

2

Es scheint, als ob Sie einen Thread-sicheren Thumbnail-Manager benötigen. I.e. eine Klasse, die selbst versteht, wie man den Zugriff auf die Dateien koordiniert.

Eine einfache Version könnte so aussehen:

%Vor%

Mit anderen Worten, zuerst überprüft der Manager, ob er die notwendige Datei kennt. Wenn dies der Fall ist, bedeutet dies, dass die Datei bereits erstellt wurde und nur den Pfad zurückgibt.

Wenn dies nicht der Fall ist, wird als nächstes geprüft, ob die Erstellung der erforderlichen Datei bereits läuft. Es macht schließlich keinen Sinn, dieselbe Datei mehr als einmal zu erstellen! Wenn es nicht bereits läuft, startet es ein Task , um die Datei zu erstellen. Wenn es bereits läuft, ruft es einfach den Task ab, der diese Operation darstellt.

In jedem Fall wird das Task erwartet, das die Operation darstellt. Die Methode kehrt an diesem Punkt zurück. Wenn die Operation abgeschlossen ist, setzt die Methode die Ausführung fort, fügt den Namen der resultierenden Datei dem Wörterbuch der abgeschlossenen Dateien hinzu und entfernt die abgeschlossene Aufgabe aus dem laufenden Wörterbuch.

Da dies natürlich eine Methode async ist, ist es für den Aufrufer die richtige Methode, um% ce_de% beim Aufruf zu verwenden, damit die Methode bei Bedarf asynchron ausgeführt werden kann, ohne den aufrufenden Thread zu blockieren. Es gibt nicht genug Kontext in Ihrer Frage, um genau zu wissen, wie das aussehen würde, aber ich nehme an, dass Sie diesen Teil herausfinden können.

    
Peter Duniho 13.02.2015 00:14
quelle