Подтвердить что ты не робот

Консольное приложение завершено до завершения асинхронного вызова

В настоящее время я пишу консольное приложение на С#, которое генерирует несколько URL-адресов, которые указывают на разные изображения на веб-сайте, а затем загружаются в виде потоков байтов с помощью WebClient.DownloadDataAsync().

Моя проблема в том, что после первого асинхронного вызова консольное приложение считает, что программа будет завершена и завершается до того, как асинхронный вызов может вернуться. Используя Console.Read(), я могу заставить консоль оставаться открытой, но это не похоже на очень хороший дизайн. Кроме того, если пользователь нажимает кнопку ввода во время процесса (пока консоль ожидает ввода), программа завершается.

Есть ли лучший способ предотвратить закрытие консоли, пока я жду возвращения асинхронного вызова?

Изменить: вызовы асинхронны, потому что я предоставляю пользователю индикатор состояния через консоль при загрузке.

4b9b3361

Ответ 1

Да. Используйте ManualResetEvent и получите асинхронный вызов обратного вызова event.Set(). Если основная процедура блокируется на event.WaitOne(), она не выйдет до завершения асинхронного кода.

Основной псевдо-код будет выглядеть так:

static ManualResetEvent resetEvent = new ManualResetEvent(false);

static void Main()
{
     CallAsyncMethod();
     resetEvent.WaitOne(); // Blocks until "set"
}

void DownloadDataCallback()
{
     // Do your processing on completion...

     resetEvent.Set(); // Allow the program to exit
}

Ответ 2

Другой вариант - просто вызвать метод async Main и подождать возвращенной задачи.

static void Main(string[] args)
{
    MainAsync(args).Wait();
}

static async Task MainAsync(string[] args)
{
    // .. code goes here
}

Начиная с .NET 4.5 вы можете теперь вызвать GetAwaiter().GetResult()

static void Main(string[] args)
{
    MainAsync(args).GetAwaiter().GetResult();
}

В чем разница между .Wait() vs .GetAwaiter(). GetResult()?

Ответ 3

Если это все, что делает ваше приложение, я бы предложил оставить асинхронный вызов; вы специально хотите, чтобы приложение зависало до завершения загрузки, поэтому использование операции async противоречит тому, что вы хотите здесь, особенно в консольном приложении.