public async Task Process(int pid, TimeSpan duration, CancellationToken token) { await await Task.Factory.StartNew(async() => { EventPipeEventSource source = null; DiagnosticsMonitor monitor = null; try { MonitoringSourceConfiguration config = null; if (_mode == PipeMode.Logs) { config = new LoggingSourceConfiguration(); } if (_mode == PipeMode.Metrics) { config = new MetricSourceConfiguration(); } monitor = new DiagnosticsMonitor(config); Stream sessionStream = await monitor.ProcessEvents(pid, duration, token); source = new EventPipeEventSource(sessionStream); if (_mode == PipeMode.Metrics) { // Metrics HandleEventCounters(source); } if (_mode == PipeMode.Logs) { // Logging HandleLoggingEvents(source); } source.Process(); } catch (DiagnosticsClientException ex) { throw new InvalidOperationException("Failed to start the event pipe session", ex); } finally { source?.Dispose(); if (monitor != null) { await monitor.DisposeAsync(); } } }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default); }
public async Task Process(int pid, TimeSpan duration, CancellationToken token) { await await Task.Factory.StartNew(async() => { EventPipeEventSource source = null; DiagnosticsMonitor monitor = null; Task handleEventsTask = Task.CompletedTask; try { MonitoringSourceConfiguration config = null; if (_mode == PipeMode.Logs) { config = new LoggingSourceConfiguration(); } if (_mode == PipeMode.Metrics) { config = new MetricSourceConfiguration(_metricIntervalSeconds); } if (_mode == PipeMode.GCDump) { config = new GCDumpSourceConfiguration(); } monitor = new DiagnosticsMonitor(config); Stream sessionStream = await monitor.ProcessEvents(pid, duration, token); source = new EventPipeEventSource(sessionStream); // Allows the event handling routines to stop processing before the duration expires. Func <Task> stopFunc = () => Task.Run(() => { monitor.StopProcessing(); }); if (_mode == PipeMode.Metrics) { // Metrics HandleEventCounters(source); } if (_mode == PipeMode.Logs) { // Logging HandleLoggingEvents(source); } if (_mode == PipeMode.GCDump) { // GC handleEventsTask = HandleGCEvents(source, pid, stopFunc, token); } source.Process(); token.ThrowIfCancellationRequested(); } catch (DiagnosticsClientException ex) { throw new InvalidOperationException("Failed to start the event pipe session", ex); } finally { source?.Dispose(); if (monitor != null) { await monitor.DisposeAsync(); } } // Await the task returned by the event handling method AFTER the EventPipeEventSource is disposed. // The EventPipeEventSource will only raise the Completed event when it is disposed. So if this task // is waiting for the Completed event to be raised, it will never complete until after EventPipeEventSource // is diposed. await handleEventsTask; }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default); }