Freigeben über


LazyThreadSafetyMode Enumeration

Definition

Gibt an, wie eine Lazy<T>-Instanz den Zugriff bei mehreren Threads synchronisiert.

public enum class LazyThreadSafetyMode
public enum LazyThreadSafetyMode
type LazyThreadSafetyMode = 
Public Enum LazyThreadSafetyMode
Vererbung
LazyThreadSafetyMode

Felder

ExecutionAndPublication 2

Sperren werden dazu verwendet, um sicherzustellen, dass eine Lazy<T>-Instanz nur von einem einzelner Thread auf threadsichere Weise initialisiert werden kann. Die Initialisierungsmethode wird effektiv in threadsicherer Weise ausgeführt (als Feldname bezeichnet Execution ). Publication des initialisierten Werts ist auch threadsicher, sodass nur ein Wert veröffentlicht und von allen Threads verwendet werden kann. Wenn die Initialisierungsmethode (oder der parameterlose Konstruktor, wenn keine Initialisierungsmethode vorhanden ist) die Sperren intern verwendet, können Deadlocks auftreten. Wenn Sie einen Lazy<T>-Konstruktor verwenden, der eine Initialisierungsmethode angibt (valueFactory-Parameter), und wenn diese Initialisierungsmethode zudem eine Ausnahme auslöst (oder bei der Behandlung einer Ausnahme ein Fehler auftritt), wenn die Value-Eigenschaft das erste Mal aufgerufen wird, dann wird die Ausnahme zwischengespeichert und bei nachfolgenden Aufrufen der Value-Eigenschaft erneut ausgelöst. Wenn Sie einen Lazy<T>-Konstruktor verwenden, der keine Initialisierungsmethode angibt, werden vom parameterlosen Konstruktor für T ausgelöste Ausnahmen nicht zwischengespeichert. In diesem Fall kann ein nachfolgender Aufruf der Value-Eigenschaft die Lazy<T>-Instanz möglicherweise erfolgreich initialisieren. Wenn die Initialisierungsmethode rekursiv auf die Value-Eigenschaft der Lazy<T>-Instanz zugreift, wird eine InvalidOperationException ausgelöst.

None 0

Die Lazy<T>-Instanz ist nicht threadsicher. Wenn mehrere Threads auf die Instanz zugreifen, ist das Verhalten nicht definiert. Verwenden Sie diesen Modus nur, wenn hohe Leistungsfähigkeit entscheidend ist und die Lazy<T>-Instanz garantiert nie von mehr als einem Thread initialisiert wird. Wenn Sie einen Lazy<T>-Konstruktor verwenden, der eine Initialisierungsmethode angibt (valueFactory-Parameter), und wenn diese Initialisierungsmethode zudem eine Ausnahme auslöst (oder bei der Behandlung einer Ausnahme ein Fehler auftritt), wenn die Value-Eigenschaft das erste Mal aufgerufen wird, dann wird die Ausnahme zwischengespeichert und bei nachfolgenden Aufrufen der Value-Eigenschaft erneut ausgelöst. Wenn Sie einen Lazy<T>-Konstruktor verwenden, der keine Initialisierungsmethode angibt, werden vom parameterlosen Konstruktor für T ausgelöste Ausnahmen nicht zwischengespeichert. In diesem Fall kann ein nachfolgender Aufruf der Value-Eigenschaft die Lazy<T>-Instanz möglicherweise erfolgreich initialisieren. Wenn die Initialisierungsmethode rekursiv auf die Value-Eigenschaft der Lazy<T>-Instanz zugreift, wird eine InvalidOperationException ausgelöst.

PublicationOnly 1

Wenn mehrere Threads gleichzeitig versuchen, eine Lazy<T>-Instanz zu initialisieren, dürfen alle Threads die Initialisierungsmethode (oder den parameterlosen Konstruktor, wenn keine Initialisierungsmethode vorhanden ist) ausführen. Der erste Thread, der die Initialisierung abgeschlossen hat, legt den Wert der Lazy<T>-Instanz fest. Dies wird in Publication den Feldnamen bezeichnet. Dieser Wert wird an alle anderen Threads zurückgegeben, die die Initialisierungsmethode gleichzeitig ausgeführt haben, sofern die Initialisierungsmethode für diese Threads keine Ausnahmen ausgelöst hat. Alle Instanzen von T, die von den konkurrierenden Threads erstellt wurden, werden verworfen. Effektiv ist die Veröffentlichung des initialisierten Werts threadsicher, sodass nur eine der initialisierten Werte veröffentlicht und von allen Threads verwendet werden kann. Wenn die Initialisierungsmethode für einen Thread eine Ausnahme auslöst, wird die Ausnahme aus der Value-Eigenschaft für diesen Thread weitergegeben. Die Ausnahme wird nicht zwischengespeichert. Der Wert der IsValueCreated-Eigenschaft bleibt false und nachfolgende Aufrufe der Value-Eigenschaft führen zur erneuten Ausführung der Initialisierungsmethode, entweder durch den Thread, bei dem die Ausnahme ausgelöst wurde oder durch andere Threads. Wenn die Initialisierungsmethode rekursiv auf die Value-Eigenschaft der Lazy<T>-Instanz zugreift, wird keine Ausnahme ausgelöst.

Hinweise

Verwenden Sie diese Enumeration, um den mode Parameter von Lazy<T> Konstruktoren anzugeben. Die Auswirkungen aller Konstruktoren auf die Threadsynchronisierung können in Bezug auf diese Enumeration beschrieben werden, unabhängig davon, ob sie Parameter haben mode .

Eine Lazy<T> Instanz wird entweder durch eine vom Benutzer angegebene Initialisierungsmethode oder durch den parameterlosen Konstruktor für T. Die Initialisierungsmethode wird vom valueFactory Parameter eines Lazy<T> Konstruktors angegeben. Die Methode gibt eine Instanz von T, die der Typ ist, der durch die Instanz von Lazy<T>. Wenn ein Konstruktor keinen Parameter hat valueFactory , wird der parameterlose Konstruktor T verwendet, um die Lazy<T> Instanz zu initialisieren. In beiden Fällen tritt die Initialisierung beim ersten Aufruf der Lazy<T>.Value Eigenschaft auf.

Zusätzlich zur Angabe der Threadsicherheit einer Lazy<T> Instanz wirkt sich diese Enumeration auf die Zwischenspeicherung von Ausnahmen aus. Wenn Ausnahmen für eine Lazy<T> Instanz zwischengespeichert werden, erhalten Sie nur eine Chance, die Instanz zu initialisieren. Wenn eine Ausnahme ausgelöst wird, wenn Sie die Lazy<T>.Value Eigenschaft zum ersten Mal aufrufen, wird diese Ausnahme zwischengespeichert und bei allen nachfolgenden Aufrufen der Lazy<T>.Value Eigenschaft erneut ausgeführt. Der Vorteil von Zwischenspeichern von Ausnahmen besteht darin, dass alle zwei Threads immer dasselbe Ergebnis erhalten, auch wenn Fehler auftreten.

Wenn Sie den PublicationOnly-Modus angeben, werden Ausnahmen nie zwischengespeichert. Wenn Sie "None" oder "ExecutionAndPublication" angeben, hängt die Zwischenspeicherung davon ab, ob Sie eine Initialisierungsmethode angeben oder den parameterlosen Konstruktor für T die Verwendung zulassen. Durch die Angabe einer Initialisierungsmethode wird das Zwischenspeichern von Ausnahmen für diese beiden Modi aktiviert. Die Initialisierungsmethode kann sehr einfach sein. Beispielsweise kann er den parameterlosen Konstruktor für T: new Lazy<Contents>(() => new Contents(), mode) in C# oder New Lazy(Of Contents)(Function() New Contents()) in Visual Basic aufrufen. Wenn Sie einen Konstruktor verwenden, der keine Initialisierungsmethode angibt, werden Ausnahmen, die vom parameterlosen Konstruktor T ausgelöst werden, nicht zwischengespeichert. In der folgenden Tabelle wird das Zwischenspeicherverhalten von Ausnahmen zusammengefasst.

Modus Verwenden der Initialisierungsmethode Verwenden eines parameterlosen Konstruktors für T
Keine Zwischengespeichert Nicht zwischengespeichert
PublikationOnly Nicht zwischengespeichert Nicht zwischengespeichert
ExecutionAndPublication Zwischengespeichert Nicht zwischengespeichert

Gilt für

Siehe auch