// // Copyright 2014 Perforce Software Inc. // using Perforce.Model; using System; using System.Collections.Generic; using System.ComponentModel; using System.Threading; namespace Perforce.Helper { public class SyncBackgroundWorker : IDisposable { private BackgroundWorker _worker; private int _interval; private string _statusMessage; private bool _runnable; public SyncBackgroundWorker() { var userPrefs = Utility.GetUserPreferences(); Init(userPrefs.SyncInterval); } public SyncBackgroundWorker(int interval) { Init(interval); } private void Init(int interval) { Log.TraceFunction(); _interval = interval; _runnable = false; _statusMessage = "INITIALIZED"; _worker = new BackgroundWorker(); _worker.WorkerSupportsCancellation = true; _worker.DoWork += new DoWorkEventHandler(this.DoWork); _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.RunWorkerCompleted); Utility.SetProperty(Constants.SYNC_WORKER, this); } public int Interval { get { return _interval; } set { if (_interval != value) { _interval = value; var userPrefs = Utility.GetUserPreferences(); userPrefs.SyncInterval = _interval; userPrefs.SaveProperty(Constants.PREFS_SYNCINTERVAL); } } } public string StatusMessage { get { return _statusMessage; } } public bool IsRunnable { get { return _runnable; } } public bool IsRunning { get { return _worker.IsBusy; } } public bool Enabled { get { var userPrefs = Utility.GetUserPreferences(); return userPrefs.SyncEnabled; } set { var userPrefs = Utility.GetUserPreferences(); userPrefs.SyncEnabled = value; userPrefs.SaveProperty(Constants.PREFS_SYNCENABLED); _runnable = userPrefs.SyncEnabled; } } public void StartSync() { if (!_worker.IsBusy) { _worker.RunWorkerAsync(); } } public void StopSync() { if (_worker.IsBusy) { _worker.CancelAsync(); _runnable = false; } } private void DoWork(object sender, DoWorkEventArgs e) { Log.TraceFunction(); if (Thread.CurrentThread.Name == null) Thread.CurrentThread.Name = "SyncBackgroundWorker"; var p4 = Utility.GetPerforceHelper(); var tools = Utility.GetToolBarViewModel(); _runnable = true; while (_runnable) { var result = p4.IsConnected(); if (result) { if (tools != null) { tools.SyncButtonEnabled = false; tools.SyncProgressVisible = true; } Log.Debug("Synchronizing workspace..."); var smdList = p4.RunSync("//..."); if (smdList != null && smdList.Count > 0) { Log.Debug(string.Format("{0} files synchronized from server", smdList.Count)); var flist = new List(); foreach (var smd in smdList) { flist.Add(PerforceHelper.UnescapePath(smd.DepotPath.Path)); } var mds = p4.GetFileMetaData(flist); if (mds != null) { foreach (var md in mds) { var item = new FileItem(); item.Metadata = md; item.LabelText = md.GetFileName(); if (md.HeadAction != P4.FileAction.Delete && md.HeadAction != P4.FileAction.MoveDelete) { Utility.GetRecentSet().Add(item); } } } } // refresh the UI UIHelper.RefreshAllSelectorsAsync(); if (tools != null) { tools.SyncButtonEnabled = true; tools.SyncProgressVisible = false; } for (var i = 0; i < _interval * 10; i++) { if (!_runnable) i = _interval * 10; Thread.Sleep(100); } } else { UIHelper.ShowMessage("LOST CONNECTION TO PERFORCE SERVER", false); StopSync(); break; } } } // This event handler demonstrates how to interpret // the outcome of the asynchronous operation implemented // in the DoWork event handler. private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Log.TraceFunction(); if (e.Cancelled) { _statusMessage = "Operation was canceled"; } else if (e.Error != null) { // There was an error during the operation. _statusMessage = String.Format("An error occurred: {0}", e.Error.Message); } else { // The operation completed normally. _statusMessage = String.Format("Sync halted normally... {0}", e.Result); } } #region CLEANUP protected virtual void Dispose(bool disposing) { if (disposing) { // dispose managed resources _worker.Dispose(); } // free native resources } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } #endregion } }