как создать асинхронное / ожидающее консольное приложение С# часы

Я новичок в async/await, и я попытался создать отзывчивые часы в качестве демонстрации. часы работали нормально, но когда я попытался перевести их в асинхронную функцию и дождался задержки, они перестали работать, отображая только время, в течение которого они работали. вот код:

public static async void clock ()
   {
      while (true)
         {
            Console.WriteLine(DateTime.Now.ToString());
            await Task.Delay(1000);
            Console.Clear();
         }
   }

а главное просто:

clock();

редактировать: кажется, что приложение не проходит этап await Task.Delay(1000);, что наводит меня на мысль, что существует бесконечная задержка, вероятно, из-за await. но, насколько я знаю, по логике этого быть не должно, я также видел несколько примеров использования await на задержке, так что это должно быть возможно сделать.


person Community    schedule 25.08.2019    source источник


Ответы (2)


Вызывая clock() из Main, вы запускаете асинхронную задачу, не дожидаясь ее завершения.

Вы можете заставить clock() возвращать Task и использовать метод clock().Wait() блока Main до тех пор, пока задача не будет завершена (чего никогда не будет, потому что clock() содержит бесконечный цикл и никогда не закончится).

Без Wait()ing для завершения задачи Main будет выполняться до завершения, что приведет к закрытию приложения.

using System;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Main 1");

        DoSomethingAsync().Wait();

        Console.WriteLine("Main 2");
    }

    public static async Task DoSomethingAsync()
    {
        Console.WriteLine("DoSomethingAsync 1");

        await Task.Delay(1000);

        Console.WriteLine("DoSomethingAsync 2");
    }
}

Вывод приложения:

Main 1
DoSomethingAsync 1
(delay of 1 second)
DoSomethingAsync 2
Main 2

Без Wait() было бы:

Main 1
DoSomethingAsync 1
Main 2

или, что более вероятно, это могло быть:

Main 1
Main 2
DoSomethingAsync 1
person Fabio Iotti    schedule 25.08.2019

Прежде всего, Task.Delay возвращает Task. Это необходимо, потому что нам может понадобиться заставить приложение ждать перед выполнением логики.

И во-вторых, если вы хотите сделать синхронным только метод часов, не рекомендуется использовать статический метод. Потому что это заблокирует весь класс для выполнения. Пожалуйста, обратитесь к этому, чтобы узнать больше о синхронном статическом и нестатические методы.

Теперь что касается реализации. Поскольку мы делаем clock() синхронным нестатическим методом. Нам нужно создать объект класса в основном методе и вызвать метод clock().

    Program p = new Program();
    p.clock();

Мы можем использовать Task.Run() для создания нового потока.

    public Task clock()
    {
        while (true)
        {
            Console.WriteLine(DateTime.Now.ToString());
            Task.Run(() => Task.Delay(1000));
            Console.Clear();
        }
    }
person Hari Krishna    schedule 25.08.2019
comment
Static не влияет на асинхронное/синхронное поведение. Это не «блокирует весь класс». Эта ссылка, на которую вы ссылаетесь, предназначена для Java и ее синхронизированной концепции. - person pinkfloydx33; 26.08.2019