diff --git a/CHANGELOG.md b/CHANGELOG.md index e4620b38..34c23d4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,10 @@ Versionsschema ist `x.x.x.x` (siehe `release.sh`). ### Geaendert +- **Doppelte Syncs verhindert (lokal).** Der Schutz gegen gleichzeitig laufende + Syncs (manuell + Auto-Sync-Timer) ist jetzt atomar (`Interlocked`) statt eines + nicht-atomaren `volatile bool`, bei dem beide in einem Zeitfenster + durchrutschen konnten. - **Ein-Richtungs-Modi sind jetzt echtes "Ersetzen".** Outlook->Starface macht das Starface-Adressbuch zu einer exakten Kopie von Outlook: Kontakte, die nur in Starface existieren (kein Pendant in Outlook), werden geloescht. diff --git a/src/StarfaceOutlookSync/UI/MainForm.cs b/src/StarfaceOutlookSync/UI/MainForm.cs index a759f699..4337e1da 100644 --- a/src/StarfaceOutlookSync/UI/MainForm.cs +++ b/src/StarfaceOutlookSync/UI/MainForm.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Drawing; using System.Linq; +using System.Threading; using System.Threading.Tasks; using System.Timers; using System.Windows.Forms; @@ -22,7 +23,9 @@ namespace StarfaceOutlookSync.UI private StatusStrip _statusBar; private ToolStripStatusLabel _statusLabel; private Timer _autoSyncTimer; - private volatile bool _syncRunning = false; + // 0 = frei, 1 = Sync laeuft. Per Interlocked atomar geschaltet, damit + // ein manueller Sync und der Auto-Sync-Timer nicht gleichzeitig starten. + private int _syncRunning = 0; public MainForm() { @@ -337,13 +340,14 @@ namespace StarfaceOutlookSync.UI private async Task RunSync(SyncProfile profile) { - if (_syncRunning) + // Atomar pruefen-und-setzen: verhindert, dass manueller Sync und + // Auto-Sync-Timer gleichzeitig denselben/einen Sync starten. + if (Interlocked.CompareExchange(ref _syncRunning, 1, 0) != 0) { SetStatus("Sync laeuft bereits, bitte warten..."); return; } - _syncRunning = true; try { SetStatus($"Synchronisiere '{profile.Name}'..."); @@ -368,7 +372,7 @@ namespace StarfaceOutlookSync.UI } finally { - _syncRunning = false; + Interlocked.Exchange(ref _syncRunning, 0); } }