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

如何让C#控制台程序无while循环等待Ctrl+C退出并运行异步方法

解决C#控制台程序等待Ctrl+C退出时的高CPU占用问题

你可以通过非忙等待的方式替代空while循环,让线程进入阻塞状态(不占用CPU资源),同时正常运行异步方法。以下是两种常用方案:

方案一:使用ManualResetEventSlim(同步阻塞方式)

ManualResetEventSlim是轻量级的同步原语,能让线程等待直到收到信号,期间不会占用CPU。

using System.Threading;
using System.Threading.Tasks;

class Program
{
    private static readonly ManualResetEventSlim _exitSignal = new ManualResetEventSlim(false);

    static void Main(string[] args)
    {
        Console.CancelKeyPress += OnCancelKeyPress;
        
        // 启动你的异步业务方法
        _ = RunAsyncOperation();

        Console.WriteLine("-> Press CTRL+C to Exit");
        _exitSignal.Wait(); // 阻塞线程,直到收到退出信号
    }

    static async Task RunAsyncOperation()
    {
        // 示例异步逻辑:每隔1秒输出一次
        while (!_exitSignal.IsSet)
        {
            Console.WriteLine("异步任务正在运行...");
            await Task.Delay(1000);
        }
    }

    static void OnCancelKeyPress(object? sender, ConsoleCancelEventArgs e)
    {
        e.Cancel = true; // 阻止系统直接终止程序
        _exitSignal.Set(); // 发送退出信号
        Console.WriteLine("CancelKeyPress fired, exit...");
    }
}

方案二:使用异步Main + TaskCompletionSource(异步编程风格)

如果你的项目使用C# 7.1及以上版本,推荐用异步Main结合TaskCompletionSource,更贴合现代异步编程模式:

using System.Threading.Tasks;

class Program
{
    private static readonly TaskCompletionSource<bool> _exitTaskSource = new TaskCompletionSource<bool>();

    static async Task Main(string[] args)
    {
        Console.CancelKeyPress += OnCancelKeyPress;
        
        // 同时运行异步业务和等待退出的任务
        await Task.WhenAll(RunAsyncOperation(), _exitTaskSource.Task);
    }

    static async Task RunAsyncOperation()
    {
        // 示例异步逻辑
        while (!_exitTaskSource.Task.IsCompleted)
        {
            Console.WriteLine("异步任务正在运行...");
            await Task.Delay(1000);
        }
    }

    static void OnCancelKeyPress(object? sender, ConsoleCancelEventArgs e)
    {
        e.Cancel = true;
        _exitTaskSource.TrySetResult(true); // 触发退出任务完成
        Console.WriteLine("CancelKeyPress fired, exit...");
    }
}

为什么原来的while循环会高CPU?

空的while (isRunning) { }是忙等待——线程会持续循环检查条件,让对应的CPU核心一直处于100%占用状态。而上面的方案都是让线程进入等待队列,直到收到信号才唤醒,完全不消耗CPU资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:23:11