You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何CancellationTokenSource会导致应用程序挂起?

Ah, I see exactly what's causing the hang here! Let's break this down step by step, then fix it.

Why Your App Is Hanging

The core problem is missing one critical line in your Console.CancelKeyPress event handler: you're not telling the CLR to stop auto-terminating the process after handling the Ctrl+C signal. Here's the play-by-play when you press Ctrl+C:

  1. The OS sends a SIGINT signal to your app, and .NET spins up a dedicated signal-handling thread to run your lambda (cancellationTokenSource.Cancel()).
  2. Calling Cancel() flips the CancellationToken's WaitHandle to a signaled state, so your main thread's loop exits immediately.
  3. Your main thread moves on to clean up: it prints the cancellation message, then hits the end of the using block, which calls CancellationTokenSource.Dispose().
  4. Meanwhile, once your event handler lambda finishes, the CLR tries to automatically terminate the process with Environment.Exit()—but your main thread is right in the middle of disposing the CancellationTokenSource.
  5. This creates a deadlock: the process termination waits for the main thread to finish its work, but the disposal operation gets stuck waiting on internal resources that are tied up by the termination flow. The result? Your app hangs forever, never reaching that final "Just before close" line.

The Fix

All you need to do is add e.Cancel = true to your event handler. This tells the CLR "I've got this—don't kill the process automatically; let me clean up properly first."

Here's the corrected code:

public static void Main()
{
    using (var cancellationTokenSource = new CancellationTokenSource())
    {
        Console.CancelKeyPress += (_, e) => 
        {
            e.Cancel = true; // This is the magic line!
            cancellationTokenSource.Cancel();
        };

        while (!cancellationTokenSource.Token.WaitHandle.WaitOne(1000))
        {
            Console.WriteLine("Still running...");
        }

        Console.WriteLine("Cancellation is requested. Trying to dispose cancellation token...");
    }

    Console.WriteLine("Just before close");
}

What Happens Now

When you press Ctrl+C:

  • The event handler stops the CLR from auto-terminating the process
  • Cancel() triggers the main thread to exit its loop
  • The main thread safely disposes the CancellationTokenSource without any deadlock
  • Your app prints the final line and exits cleanly

If you didn't care about clean cleanup, you could just call Environment.Exit() directly in the event handler—but skipping disposal is risky if you're using resources that need explicit cleanup (like file handles or network connections).

内容的提问来源于stack exchange,提问作者Alex Zhukovskiy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:42:10