OpLock-Klasse
Leichtgewichtiger, nicht threadsicherer Sperrmechanismus, um die Ausführung der selben Operation durch mehrere Methoden gegenseitig zu sperren.
Diese Klasse kann verwendet werden, wenn sich mehrere Operationen in einer GUI- oder Single-Thread-Anwendung gegenseitig ausschließen. Im Gegensatz zum lock
-Schlüsselwort von C# werden mehrere gleichzeitige Aufrufe nicht serialisiert, sondern vollständig verhindert. Anstelle den zweiten Aufruf abzubrechen kann auch jedes andere Verhalten implementiert werden, wie z. B. eine Interaktion mit der ersten laufenden Instanz. Da keine threadsichere Sperre verwendet wird, benötigt diese Klasse weniger Ressourcen und ist dadurch performanter. Außerdem ermöglicht die Nutzung eines OpFlags auch eine Abfrage des aktuellen Zustands der Sperre.
Kompatibilität:
Beispiel
Die folgenden Beispiele zeigen, wie die OpLock- und OpFlag-Klassen verwendet werden können. Im ersten Beispiel werden zwei gegenseitige TextBox-Updates gesperrt:
private OpFlag isUpdating = new OpFlag();
private void TextBox1_TextChanged(object sender, EventArgs e)
{
// Zustand der Sperre prüfen und ggf. abbrechen
if (isUpdating.IsSet) return;
// Sperre setzen und Operation durchführen
using (new OpLock(isUpdating))
{
// Durch diesen Aufruf wird die andere Ereignismethode aufgerufen, die
// aufgrund der gesetzten Sperre aber nichts tut.
TextBox2.Text = TextBox1.Text;
}
}
private void TextBox2_TextChanged(object sender, EventArgs e)
{
// Zustand der Sperre prüfen und ggf. abbrechen
if (isUpdating.IsSet) return;
// Sperre setzen und Operation durchführen
using (new OpLock(isUpdating))
{
// Durch diesen Aufruf wird die andere Ereignismethode aufgerufen, die
// aufgrund der gesetzten Sperre aber nichts tut.
TextBox1.Text = TextBox2.Text;
}
}
Das zweite Beispiel zeigt eine ViewModel-Klasse, in der das geöffnete Editorfenster den Import-Befehl sperrt:
class MainWindowViewModel : ViewModelBase
{
// Referenz auf das Editorfenster
private EditorWindow editorView;
// Speichert den Sperrzustand des Editors
private OpFlag editorFlag = new OpFlag();
// Commands für das Anwendungsmenü
public DelegateCommand EditorCommand { get; private set; }
public DelegateCommand ImportCommand { get; private set; }
// ViewModel-Konstruktor
public MainWindowViewModel()
{
// Initialisieren der Commands
EditorCommand = new DelegateCommand(OnEditorCommand);
ImportCommand = new DelegateCommand(OnImportCommand, CanExecuteImport);
// Wenn sich der Sperrzustand des Editors ändert, muss WPF darüber
// informiert werden, dass sich die Verfügbarkeit des Import-Befehls
// geändert hat.
editorFlag.ValueChanged += (s, e) =>
{
ImportCommand.RaiseCanExecuteChanged();
};
}
// Behandelt den Editor-Befehl
private void OnEditorCommand()
{
// Wenn die Sperre gesetzt ist, ist das Editorfenster bereits geöffnet.
// In diesem Fall muss es nur in den Vordergrund gebracht werden.
// Andernfalls muss es neu erstellt und geöffnet werden.
if (!editorFlag.IsSet)
{
// Neues Editorfenster erstellen
editorView = new EditorWindow();
// Weitere Initialisierung...
// Die Sperre wird jetzt gesetzt
editorFlag.Enter();
// Freigeben der Sperre, wenn das Fenster geschlossen wurde
editorView.Closed += (s, e) => { editorFlag.Leave(); };
// Fenster anzeigen, nicht modal (das Hauptfenster ist weiter verfügbar)
editorView.Show();
}
else
{
// Fenster fokussieren
editorView.Focus();
}
}
// Gibt an, ob der Import-Befehl derzeit zur Verfügung steht. Das ist immer
// dann der Fall, wenn das Editorfenster nicht geöffnet ist.
private bool CanExecuteImport()
{
return !editorFlag.IsSet;
}
// Behandelt den Import-Befehl
private void OnImportCommand()
{
// ...
}
}
Download
OpLock.cs2,4 KiBQuelltext der OpLock-Klasse
Lizenz und Nutzungsbedingungen
Vervielfältigung und Weiterverbreitung dieser Datei, verändert oder unverändert, sind gestattet, vorausgesetzt die Urheberrechtsangabe und dieser Hinweis bleiben erhalten. Diese Datei wird wie vorliegend ohne jegliche Garantie oder Gewährleistung angeboten. (GNU All-Permissive-Lizenz)
Statistische Daten
- Erstellt am 2012-08-06.