private void DoProcess(ZPushAccount account, GABHandler gab, IZPushItem item) { // Multiple accounts - and therefore multiple folders - may use the same GAB. // One process the items from the first associated account if (account != gab.ActiveAccount) { Logger.Instance.Trace(this, "Ignoring GAB message: {0} - {1}", account, item); return; } ++_processing; Logger.Instance.Trace(this, "Processing GAB message: {0} - {1}", account, _processing); CompletionTracker completion = new CompletionTracker(() => OnGabSyncFinished(gab)); using (completion.Begin()) { try { gab.Process(completion, item); // TODO: this will probably run while still processing, use completion tracker DoEmptyDeletedItems(); } finally { Logger.Instance.Trace(this, "Processed GAB message: {0} - {1}", account, _processing); --_processing; } } }
private static async void DisposeOnCompletion(CompletionTracker tracker, ProjectCollection projectCollection) { await tracker.PendingCompletion; Console.WriteLine("DISPOSING COLLECTION"); projectCollection.UnloadAllProjects(); }
public TaskDispatcher(int?maxParallelism = null) { tracker = new CompletionTracker(); actionQueue = new ActionQueue( maxDegreeOfParallelism: maxParallelism ?? Environment.ProcessorCount + 2, tracker: tracker, priorityCount: 2 /*, * boundedCapacity: 128*/); }
private void ProcessChunkBody(CompletionTracker completion, IZPushItem item, ChunkIndex index) { // Process the body foreach (var entry in JSONUtils.Deserialise(item.Body)) { string id = entry.Key; Dictionary <string, object> value = (Dictionary <string, object>)entry.Value; Tasks.Task(completion, _feature, "CreateItem", () => CreateObject(index, id, value)); } }
public static ProjectCollectionScope GetProjectCollectionScope() { lock (s_syncLock) { s_projectCollectionUseCount++; if ((s_projectCollectionUseCount % ProjectCollectionUseThreshold) == 0) { s_completionTracker?.OnComplete(); s_completionTracker = new CompletionTracker(); s_projectCollection = new ProjectCollection(); s_completionTracker.OnStart(); DisposeOnCompletion(s_completionTracker, s_projectCollection); } return(new ProjectCollectionScope(s_projectCollection, s_completionTracker)); } }
private IEnumerable <string> GetFiles(string rootDirectory) { CompletionTracker tracker = new CompletionTracker(); BlockingCollection <string> directories = new BlockingCollection <string>(); BlockingCollection <string> files = new BlockingCollection <string>(); QueueDirectory(rootDirectory, tracker, directories); tracker.PendingCompletion.ContinueWith(t => directories.CompleteAdding()); ParallelConsume(directories, directory => { try { foreach (var childDirectory in Directory.GetDirectories(directory)) { if (Filter.IncludeDirectory(this, childDirectory)) { QueueDirectory(childDirectory, tracker, directories); } } foreach (var file in Directory.GetFiles(directory, SearchPattern)) { if (Filter.IncludeFile(this, file)) { files.Add(file); } } } finally { CompleteDirectory(directory, tracker); } }, () => { files.CompleteAdding(); }); return(files.GetConsumingEnumerable()); }
private void ProcessMessages(CompletionTracker completion) { if (!_feature.ProcessFolder) { return; } DetermineSequence(); if (CurrentSequence == null) { return; // No messages to process } if (!_feature.ProcessItems) { return; } // Process the messages foreach (IZPushItem item in Folder.Items.Typed <IZPushItem>()) { // Store the entry id to fetch again later, the item will be disposed string entryId = item.EntryID; Logger.Instance.Trace(this, "Checking chunk: {0}", item.Subject); if (_feature.ProcessItems2) { Tasks.Task(completion, _feature, "ProcessChunk", () => { using (IItem item2 = Folder.GetItemById(entryId)) { if (item2 != null) { ProcessMessage(completion, (IZPushItem)item2); } } }); } } }
/// <summary> /// Processes the GAB message(s). /// </summary> /// <param name="item">If specified, this item has changed. If null, means a global check should be performed</param> public void Process(CompletionTracker completion, IZPushItem item) { using (CompletionTracker.Step step = completion?.Begin()) { try { if (item == null) { if (Folder != null) { ProcessMessages(completion); } } else { ProcessMessage(completion, item); } } catch (Exception e) { Logger.Instance.Error(this, "Exception in GAB.Process: {0}", e); } } }
private void CompleteDirectory(string directory, CompletionTracker tracker) { tracker.OnComplete(); }
private void QueueDirectory(string directory, CompletionTracker tracker, BlockingCollection <string> directories) { tracker.OnStart(); directories.Add(directory); }
public static ResultType Execute <ResultType>(string resourcePrefix, Func <CancellationToken, CompletionTracker, ResultType> action) { // TODO: merge with above Logger.Instance.Info(typeof(ProgressDialog), "Opening"); // Determine the UI context, creating a new one if required if (SynchronizationContext.Current == null) { SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext()); } var context = TaskScheduler.FromCurrentSynchronizationContext(); // Create the dialog, so it is available for the task ProgressDialog dlg = new ProgressDialog(); // Set the strings dlg.Text = StringUtil.GetResourceString(resourcePrefix + "_Title"); dlg.labelMessage.Text = StringUtil.GetResourceString(resourcePrefix + "_Label"); // Start the task Exception caught = null; Task <ResultType> task = null; // And close the dialog when done CompletionTracker tracker = new CompletionTracker(() => { // This extra step is needed to go back into the thread context task.ContinueWith(_ => { dlg._isComplete = true; dlg.DialogResult = DialogResult.OK; }, context); }); task = Task.Factory.StartNew( () => { try { return(action(dlg.cancel.Token, tracker)); } catch (Exception e) { caught = e; return(default(ResultType)); } }, dlg.cancel.Token); dlg.task = task; // Show the dialog if (dlg.ShowDialog() != DialogResult.OK) { return(default(ResultType)); } // Rethrow any exception. // The framework already handles this, but that causes breaks into the debugger if (caught != null) { throw caught; } // Result the result return(task.Result); }
/// <summary> /// Performs a full resync. /// </summary> /// <param name="completion">The completion tracker, or null.</param> /// <param name="accounts">The accounts to resync, or null to resync all</param> internal void FullResync(CompletionTracker completion, ZPushAccount[] accounts) { try { // TODO: implement per-account resyncing Logger.Instance.Trace(this, "FullResync begin: {0}", _processing); BeginProcessing(); // Delete any contacts folders in the local store if (DeleteExistingFolder) { using (IStore store = ZPushLocalStore.GetInstance(ThisAddIn.Instance)) { if (store != null) { using (IFolder root = store.GetRootFolder()) { foreach (IFolder folder in root.GetSubFolders <IFolder>().DisposeEnum()) { try { if (IsGABContactsFolder(folder, accounts)) { Logger.Instance.Debug(this, "FullResync: Deleting contacts folder: {0}", folder.Name); folder.Delete(); } } catch (System.Exception e) { Logger.Instance.Error(this, "FullResync: Exception deleting contacts folder: {0}", e); } } } } } } // Do the resync using (completion.Begin()) { foreach (GABHandler gab in _gabsByDomainName.Values) { // Check if the gab is appropriate for the accounts if (accounts == null || accounts.Contains(gab.ActiveAccount)) { completion.Begin(); CompletionTracker partCompletion = new CompletionTracker(() => { OnGabSyncFinished(gab); completion.End(); }); Logger.Instance.Debug(this, "FullResync: Starting resync: {0}", gab.DisplayName); Tasks.Task(partCompletion, this, "FullResync", () => { gab.FullResync(partCompletion); }); } } } } finally { EndProcessing(); Logger.Instance.Trace(this, "FullResync done: {0}", _processing); } }
public ProjectCollectionScope(ProjectCollection collection, CompletionTracker tracker) { Collection = collection; Tracker = tracker; }
public void SetUp() { _tracker = new CompletionTracker(); }
private void ProcessMessage(CompletionTracker completion, IZPushItem item) { if (!_feature.ProcessMessage) { return; } // Check if the message is for the current sequence ChunkIndex?optionalIndex = ChunkIndex.Parse(item.Subject); if (optionalIndex == null) { Logger.Instance.Trace(this, "Not a chunk: {0}", item.Subject); return; } if (optionalIndex.Value.numberOfChunks != CurrentSequence) { // Try to update the current sequence; this message may indicate that it has changed DetermineSequence(); // If it is still not for the current sequence, it's an old message if (optionalIndex.Value.numberOfChunks != CurrentSequence) { Logger.Instance.Trace(this, "Skipping, wrong sequence: {0}", item.Subject); return; } } ChunkIndex index = optionalIndex.Value; // Check if the message is up to date string lastProcessed = GetChunkStateString(index); if (lastProcessed == item.Location) { Logger.Instance.Trace(this, "Already up to date: {0} - {1}", item.Subject, item.Location); return; } // Process it Logger.Instance.Trace(this, "Processing: {0} - {1} - {2}", item.Subject, item.Location, lastProcessed); _feature?.BeginProcessing(); try { if (_feature.ProcessMessageDeleteExisting) { // Delete the old contacts from this chunk using (ISearch <IItem> search = Contacts.Search <IItem>()) { search.AddField(PROP_SEQUENCE, true).SetOperation(SearchOperation.Equal, index.numberOfChunks); search.AddField(PROP_CHUNK, true).SetOperation(SearchOperation.Equal, index.chunk); foreach (IItem oldItem in search.Search()) { Logger.Instance.Trace(this, "Deleting GAB entry: {0}", oldItem.Subject); oldItem.Delete(); } } } // Create the new contacts ProcessChunkBody(completion, item, index); // Update the state SetChunkStateString(index, item.Location); } finally { _feature?.EndProcessing(); } }
public void FullResync(CompletionTracker completion) { ClearContacts(); Process(completion, null); }