public async Task Run() { using (CancellationTokenSource tokenSource = new CancellationTokenSource()) using (CancellationTokenSource monitorSource = new CancellationTokenSource()) { Task memoryUsageMonitor = StartMemoryUsageMonitor(monitorSource.Token); Dictionary <string, Task> processTasks = new Dictionary <string, Task>(); foreach (var plugin in _plugins) { // start process plugins background _trace.Trace($"Start process task for plugin '{plugin.FriendlyName}'"); var task = RunAsync(plugin, tokenSource.Token); processTasks[plugin.FriendlyName] = task; } // waiting for job finish event await _jobFinished.Task; tokenSource.Cancel(); _trace.Trace($"Wait for all plugins finish process outputs."); foreach (var task in processTasks) { try { await task.Value; _trace.Trace($"Plugin '{task.Key}' finished log process."); } catch (Exception ex) { _trace.Output($"Plugin '{task.Key}' failed with: {ex}"); } } // Stop monitor monitorSource.Cancel(); await memoryUsageMonitor; // job has finished, all log plugins should start their finalize process Dictionary <string, Task> finalizeTasks = new Dictionary <string, Task>(); foreach (var plugin in _plugins) { string typeName = plugin.GetType().FullName; if (!_shortCircuited[typeName].Task.IsCompleted) { _trace.Trace($"Start finalize for plugin '{plugin.FriendlyName}'"); var finalize = plugin.FinalizeAsync(_pluginContexts[typeName]); finalizeTasks[plugin.FriendlyName] = finalize; } else { _trace.Trace($"Skip finalize for short circuited plugin '{plugin.FriendlyName}'"); } } _trace.Trace($"Wait for all plugins finish finalization."); foreach (var task in finalizeTasks) { try { await task.Value; _trace.Trace($"Plugin '{task.Key}' finished job finalize."); } catch (Exception ex) { _trace.Output($"Plugin '{task.Key}' failed with: {ex}"); } } _trace.Trace($"All plugins finished finalization."); } }
// user log (job log) public void Output(string message) { _trace.Output($"{_pluginName}: {message}"); }