private void Synchronize(bool startFromScratch = false) { lock (startSyncLock) { if (isSyncing) { changesWhileSync = true; return; } isSyncing = true; changesWhileSync = false; } if (SyncStarted != null) { SyncStarted(this, null); } if (startFromScratch) { if (File.Exists(metadataFile)) { File.Delete(metadataFile); } } var fileProvider = new FileSyncProvider( localFolder, new FileSyncScopeFilter(), FileSyncOptions.RecycleDeletedFiles | FileSyncOptions.RecycleConflictLoserFiles, Path.GetDirectoryName(metadataFile), Path.GetFileName(metadataFile), Path.GetTempPath(), null ); fileProvider.AppliedChange += (s, e) => AppliedChange(s, e.ChangeType, e.OldFilePath, e.NewFilePath); fileProvider.SkippedChange += (s, e) => { var t = e; }; var remote = new MegaKnowledgeProvider(remoteStore); if (startFromScratch) { remote.ResetDatabase(); } remote.AppliedChange += (s, e) => AppliedChange(s, e.ChangeType, e.OldFilePath, e.NewFilePath); // do we need this? remote.DestinationCallbacks.ItemConstraint += (s, e) => { e.SetResolutionAction(ConstraintConflictResolutionAction.SkipChange); }; remote.DestinationCallbacks.ItemConflicting += (s, e) => { e.SetResolutionAction(ConflictResolutionAction.Merge); }; try { var agent = new SyncOrchestrator(); agent.RemoteProvider = remote; agent.Direction = SyncDirectionOrder.UploadAndDownload; agent.LocalProvider = fileProvider; var status = agent.Synchronize(); remoteStore.CleanTemp(); if (remote.NeedResync) { syncTimer.Stop(); syncTimer.Start(); } } catch (Exception e) { remote.ResetDatabase(); if (File.Exists(metadataFile)) { File.Delete(metadataFile); } OnError("Sync has encountered a severe problem. Trying to resync from scratch...", e); syncTimer.Stop(); syncTimer.Start(); } finally { fileProvider.Dispose(); remote = null; lock (startSyncLock) { if (changesWhileSync) { syncTimer.Stop(); syncTimer.Start(); } isSyncing = false; } if (SyncEnded != null) { SyncEnded(this, null); } } }