public void Queue(PendingAction action) { lock (this) { // Caso estremo: ci sono più di 5000000 di modifiche in sospeso! Aspetta prima di permetterne ulteriori accodamenti. while (_list.Count() == MAX_QUEUED_LIMIT) Monitor.Wait(this); // Controllo se l'azione corrente è già in esecuzione dal thread Sync... PendingAction currentAction= SynchThread.Instance.GetWorkingAction(); if (currentAction != null && action.FullPath == currentAction.FullPath) { // Se il syncthread stava lavorando sullo steso file, annulla l'azione che sta compiendo perché sarebbe vana. currentAction.Stop(); currentAction.Join(); SetDone(currentAction); } /* * Se la richiesta è relativa ad un file che abbiamo già inserito nel dizionario, * occorre spostarla in coda alla lista (in termini sequenziali), aggiornando * l'indice nel dizionario relativo alla lista. */ if (_dict.ContainsKey(action.FullPath)) { _list.Remove(action.FullPath); _dict.Remove(action.FullPath); } _list.Add(action.FullPath); _dict.Add(action.FullPath, action); Monitor.Pulse(this); } }
/// <summary> /// Rimuoviamo un'azione appena soddisfatta. /// </summary> /// <param name="pa"></param> public void SetDone(PendingAction pa) { lock (this) { // La gestione del pull è differente dalle altre. if (pa is PendingPull) { PendingPull pullAction = pa as PendingPull; if (_pullNotifications > 1) { _pullNotifications = 1; } else if (_pullNotifications > 0) { _pullNotifications = 0; } _pullNotifications = 0; // Altrimenti lascia tutto com'è, alla prossima invocazione di GetJob() verrà ritornato ancora un PullPending come actions return; } else { if (!_dict.ContainsKey(pa.FullPath)) throw new ApplicationException("Errore gravissimo! Si tenta di fare una setDone su un oggetto non più presente nel dizionario."); _list.Remove(pa.FullPath);//Ricerca?! _dict.Remove(pa.FullPath); } } }
/// <summary> /// Questa è la funzione che il thread dovrà eseguire. /// </summary> private void Run() { while (!_switchOff) { while (!ApplicationState.Instance.STEnabled) { lock (ApplicationState.Instance) { Monitor.Wait(ApplicationState.Instance); } } _currentAction = PendingActions.Instance.GetJob(); try { if (_currentAction.Handle()) { lock (_currentAction) { PendingActions.Instance.SetDone(_currentAction); if (OnActionPerformed != null) OnActionPerformed(new SynchThreadActionPerformedArgs(_currentAction)); } } } catch (Exception e) { // TODO log // Notifica che è accadeuto un errore se qualcuno si è registrato all'evento. if (OnError != null) { SynchThreadErrorArgs args = new SynchThreadErrorArgs(e, _currentAction); OnError(args); } } finally { if (_currentAction != null) { _currentAction.SetEnd(); _currentAction = null; } } } }
public SynchThreadErrorArgs(Exception e, PendingAction pa) { _exception = e; _pa = pa; }
public SynchThreadActionPerformedArgs(PendingAction pa) { _pa = pa; }