Консольное приложение C# не закрывается до тех пор, пока не будет нажата комбинация клавиш CTRL+C без цикла while

потому что while() это приводит к высокой загрузке ЦП, как я могу запустить асинхронный метод, но дождаться нажатия CTRL + C перед выходом из программы?

class Program
{
    public static bool isRunning = true;
    static void Main(string[] args)
    {
        Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
        // run async method...
        Console.WriteLine("-> Press CTRL+C to Exit");
        while (isRunning) { } // <- wait but without this
    }

    static void Console_CancelKeyPress(object? sender, ConsoleCancelEventArgs e)
    {
        e.Cancel = true;
        isRunning = false;
        Console.WriteLine("CancelKeyPress fired, exit...");
    }
}

Принимает ли ваш асинхронный метод токен отмены?

gunr2171 31.03.2024 22:17

нет токена отмены

uingtea 31.03.2024 22:25
Learn.microsoft.com/en-us/dotnet/api/…
Hans Passant 31.03.2024 22:27

Описанное вами поведение не является типичным поведением консольного приложения. Вместо этого вы можете рассмотреть возможность создания приложения Windows Forms или приложения WPF. Почему вы решили создать консольное приложение?

user246821 31.03.2024 22:29

На самом деле я бы сказал, что служба Windows более подходит, чем приложение с графическим интерфейсом.

gunr2171 31.03.2024 22:48

Это то, что помогает? stackoverflow.com/questions/2586612/…

gunr2171 31.03.2024 22:50
// run async method... пожалуйста, покажите настоящий код, потому что у вас void Main нет async Task Main
Charlieface 31.03.2024 23:09

@Charlieface это HttpListener с BeginGetContext

uingtea 01.04.2024 00:50

Не вижу этого в вашем посте, но вам понадобится EndGetContext, иначе это будет зацикливаться навсегда.

Charlieface 01.04.2024 00:56

Изучите расширения хостинга Microsoft (Nuget); здесь вы заново изобретаете решенную проблему. Время жизни консоли с выходом Ctrl+C является для нее одной из базовых/стандартных конфигураций.

Mathieu Guindon 01.04.2024 01:47
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
79
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Быстрый «хак» — добавить Task.Delay, чтобы ваш основной поток не использовал ресурсы:

Task.Run(async () =>
{
    // Do your work here
    for (int i = 0; ; i++)
    {
        Console.WriteLine(i);
        await Task.Delay(500);
    }
});

Console.WriteLine("Press Ctrl+C to exit");
while (true)
{
    await Task.Delay(1000);
}

Более правильный способ — использовать TaskCompletionSource:

var cts = new TaskCompletionSource();

_ = Task.Run(async () =>
{
    // Do your work here
    for (int i = 0; i < 5; i++)
    {
        Console.WriteLine(i);
        await Task.Delay(500);
    }

    // Done: report it as done
    cts.TrySetResult();
});

Console.WriteLine("Press Ctrl+C to exit or wait until the app finishes");
await cts.Task;

Если ваша работа бесконечна и останавливается только на вводе пользователей, просто не звоните TrySetResult никуда.

Ответ принят как подходящий

это так просто, но когда ты застреваешь, ты забываешь это простое решение

он использует 0% загрузки ЦП вместо while(true) использования 10-50% ЦП

Console.WriteLine("Press CTRL+C to Exit");
Console.ReadKey();

Метод ReadKey/ReadLine выполняется синхронно. То есть блокирует пока не будет нажата клавиша

Другие вопросы по теме