Summary
Pressing Ctrl+C while the Aspire CLI is starting an AppHost can take too long to end the CLI process. This is especially noticeable when startup is stuck waiting for AppHost/backchannel readiness.
Repro context
While investigating a TypeScript AppHost startup issue:
cd D:\dev\git\dogfood\helllo
aspire start --debug
The CLI got stuck during startup waiting for the child AppHost/backchannel path. Pressing Ctrl+C does not feel immediate; shutdown can take several seconds before the CLI process exits.
What I expected
Ctrl+C should request cancellation immediately and the CLI should exit promptly, or at least provide visible feedback that it is waiting on child process shutdown and then force completion quickly.
What happens
The CLI can sit for multiple seconds during cancellation. The current cancellation flow has a few places that appear to add delay:
Program.Main creates ConsoleCancellationManager(processTerminationTimeout: TimeSpan.FromSeconds(5)).
ConsoleCancellationManager.Cancel(...) calls _cts.Cancel() and then synchronously waits for the command handler:
if (startedHandler is null || !startedHandler.Wait(_processTerminationTimeout))
{
_processTerminationCompletionSource.TrySetResult(forcedTerminationExitCode);
}
Program.Main is waiting on:
Task.WhenAny(handlerTask, cancellationManager.ProcessTerminationCompletionSource.Task)
but ProcessTerminationCompletionSource is only signaled after the synchronous wait in the signal handler finishes.
- Separately, AppHost startup timeout/cancellation uses another 5-second wait in
RunCommand.CancelAppHostStartupAsync:
await pendingRun.WaitAsync(s_appHostStartupCancellationTimeout, _timeProvider)
So a stuck startup path can accumulate delays before the CLI returns.
Suggested investigation
Consider changing the cancellation manager so the Ctrl+C handler does not synchronously block for the full termination timeout before Program.Main can observe cancellation. For example:
- Signal cancellation immediately and schedule the forced-completion timeout asynchronously.
- Emit a debug/info log when Ctrl+C is received and when forced completion is triggered.
- Make a second Ctrl+C force termination immediately.
- Audit
RunCommand.CancelAppHostStartupAsync and child process teardown so startup cancellation does not add another long wait without user-visible progress.
Related observations
In the TypeScript AppHost repro, the profile showed the long wait in:
aspire/cli/start_apphost.wait_for_backchannel
aspire/cli/run_apphost.wait_for_backchannel
The remotehost server itself was still alive/listening, and the actual underlying startup failure in a managed repro was missing npm. This issue is specifically about the Ctrl+C/shutdown responsiveness when the CLI is stuck in one of these startup waits.
Summary
Pressing Ctrl+C while the Aspire CLI is starting an AppHost can take too long to end the CLI process. This is especially noticeable when startup is stuck waiting for AppHost/backchannel readiness.
Repro context
While investigating a TypeScript AppHost startup issue:
cd D:\dev\git\dogfood\helllo aspire start --debugThe CLI got stuck during startup waiting for the child AppHost/backchannel path. Pressing Ctrl+C does not feel immediate; shutdown can take several seconds before the CLI process exits.
What I expected
Ctrl+C should request cancellation immediately and the CLI should exit promptly, or at least provide visible feedback that it is waiting on child process shutdown and then force completion quickly.
What happens
The CLI can sit for multiple seconds during cancellation. The current cancellation flow has a few places that appear to add delay:
Program.MaincreatesConsoleCancellationManager(processTerminationTimeout: TimeSpan.FromSeconds(5)).ConsoleCancellationManager.Cancel(...)calls_cts.Cancel()and then synchronously waits for the command handler:Program.Mainis waiting on:but
ProcessTerminationCompletionSourceis only signaled after the synchronous wait in the signal handler finishes.RunCommand.CancelAppHostStartupAsync:So a stuck startup path can accumulate delays before the CLI returns.
Suggested investigation
Consider changing the cancellation manager so the Ctrl+C handler does not synchronously block for the full termination timeout before
Program.Maincan observe cancellation. For example:RunCommand.CancelAppHostStartupAsyncand child process teardown so startup cancellation does not add another long wait without user-visible progress.Related observations
In the TypeScript AppHost repro, the profile showed the long wait in:
aspire/cli/start_apphost.wait_for_backchannelaspire/cli/run_apphost.wait_for_backchannelThe remotehost server itself was still alive/listening, and the actual underlying startup failure in a managed repro was missing
npm. This issue is specifically about the Ctrl+C/shutdown responsiveness when the CLI is stuck in one of these startup waits.