Ich frage mich, ob dies Thread-Safe ist oder (wenn nicht), wie ich es sicher machen kann. Es wird von einem Zeitgeber genannt:Muss ich ein Bool sperren, wenn ich es in zwei aufeinanderfolgenden Anweisungen lese/schreibe?
private volatile bool _isSynchronizing;
private void SynchronizeSessionCache(object state = null)
{
if (_isSynchronizing)
{
Log.Warn($"Aborted synchronization of SessionCache with SessionManager because we are already synchronizing. Interval is: {SynchronizationInterval}");
return;
}
_isSynchronizing = true;
bool lockWasTaken = false;
try
{
// some code that doesn't need a lock ...
// ...
// lock this part
Monitor.Enter(_lockObject, ref lockWasTaken);
// main code ...
}
finally // omitted catch
{
_isSynchronizing = false;
if(lockWasTaken)
Monitor.Exit(_lockObject);
}
}
Meine Sorge ist, dass es, dass ein Thread überprüft _isSynchronizing
am Anfang seiner Methode möglich sein könnte, und es ist false
zu diesem Zeitpunkt. Dann kommt ein anderer Thread in den Körper, weil er noch nicht auf true
von thread1 gesetzt ist. Ist das möglich, auch wenn _isSynchronizing
volatile
ist? Wenn ja, wie kann diese Methode threadsicher gemacht werden?
Wenn ich es richtig verstehe volatile
kann solche Race-Bedingungen nicht verhindern, sondern stellt nur sicher, dass die Variable nicht zwischengespeichert wird, so dass alle Threads immer den aktuellen Wert lesen.
Ja, es ist möglich, dass beide Laufflächen die erste Prüfung bestehen. Aber dann innerhalb der Methode haben Sie eine Sperre, so dass Sie erwarten, dass mehrere Threads eingeben, also was ist die Idee? – Evk
@Evk: Ich erwarte nicht, dass mehrere Threads eingeben. Das '_lockObject' wird auch in anderen Methoden und Ereignissen verwendet, die Zugriff auf freigegebene Ressourcen benötigen. Dies muss während der Synchronisierung gesperrt werden. Es sollte nie passieren, dass mehrere Threads gleichzeitig eintreffen. Deshalb benutze ich das '_isSynchronizing' -Flag. –
Gut, dann würde ich hier einfach die Sperrung verwenden. – Evk