diff --git a/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/EventPipeSession.cs b/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/EventPipeSession.cs index 4de76a9896..fd7508c24a 100644 --- a/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/EventPipeSession.cs +++ b/src/Microsoft.Diagnostics.NETCore.Client/DiagnosticsClient/EventPipeSession.cs @@ -164,15 +164,8 @@ private bool TryCreateStopMessage(out IpcMessage stopMessage) protected virtual void Dispose(bool disposing) { - // If session being disposed hasn't been stopped, attempt to stop it first - if (!_stopped) - { - try - { - Stop(); - } - catch { } // swallow any exceptions that may be thrown from Stop. - } + // Do not call Stop() here. Trying to do so now might block indefinitely if the runtime is unresponsive and we don't want blocking behavior in Dispose(). + // If the caller wants to ensure that all rundown events are captured they should call Stop() first, then process the EventStream until it is complete, then call Dispose(). if (!_disposedValue) { diff --git a/src/Tools/dotnet-stack/ReportCommand.cs b/src/Tools/dotnet-stack/ReportCommand.cs index 4684d58d0b..645de24def 100644 --- a/src/Tools/dotnet-stack/ReportCommand.cs +++ b/src/Tools/dotnet-stack/ReportCommand.cs @@ -78,12 +78,13 @@ private static async Task Report(CancellationToken ct, IConsole console, in // is too short in a given environment, e.g., resource constrained systems // N.B. - This trace INCLUDES rundown. For sufficiently large applications, it may take non-trivial time to collect // the symbol data in rundown. - using (EventPipeSession session = client.StartEventPipeSession(providers)) + EventPipeSession session = await client.StartEventPipeSessionAsync(providers, requestRundown:true, token:ct).ConfigureAwait(false); + using (session) using (FileStream fs = File.OpenWrite(tempNetTraceFilename)) { - Task copyTask = session.EventStream.CopyToAsync(fs); - await Task.Delay(duration).ConfigureAwait(false); - session.Stop(); + Task copyTask = session.EventStream.CopyToAsync(fs, ct); + await Task.Delay(duration, ct).ConfigureAwait(false); + await session.StopAsync(ct).ConfigureAwait(false); // check if rundown is taking more than 5 seconds and add comment to report Task timeoutTask = Task.Delay(TimeSpan.FromSeconds(5)); @@ -147,6 +148,10 @@ private static async Task Report(CancellationToken ct, IConsole console, in } } } + catch (OperationCanceledException) + { + return -1; + } catch (Exception ex) { Console.Error.WriteLine($"[ERROR] {ex}");