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);
        }
Example #2
0
        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);
        }