Страницы

Поиск по вопросам

четверг, 12 декабря 2019 г.

Как вызвать асинхронный метод из Main?

#c_sharp #async_await


Работает ли данный код асинхронно? По идее, должен, но у меня почему-то основной
поток блокируется.

static void Main(string[] args)
{
    DoSomething();
    Console.WriteLine("Now u can type something");
    Console.ReadLine();
}        

public static async void DoSomething()
{
    using (FilmContext context = new FilmContext())
    {
        var c = await (from b in context.Films select b).ToListAsync();

        foreach (var a in c)
        {
            Console.WriteLine(a.Descripton);
        }
    }
}

    


Ответы

Ответ 1



Смотрите. Вы хотите, чтобы вывод в функции Main происходил после окончания DoSomething? Значит, вам нужно (асинхронно) дождаться окончания работы этой функции. Для этого нужны следующие изменения: Функция должна возвращать не void (async void вообще нужен лишь в специфических случаях, т. к. его невозможно дождаться через await), а Task. Вы должны в Main дождаться окончания DoSomething, используя await DoSomething();. Чтобы в функции Main можно было использовать await, проще всего сделать её тоже асинхронной. В свежих версиях C# (начиная с C# 7.1) это легко делается при помощи объявления static async Task Main(string[] args). Итого: static async Task Main(string[] args) { await DoSomething(); Console.WriteLine("Now u can type something"); Console.ReadLine(); } public static async Task DoSomething() { using (FilmContext context = new FilmContext()) { var c = await (from b in context.Films select b).ToListAsync(); foreach (var a in c) { Console.WriteLine(a.Descripton); } } } Если вам нужно, чтобы выполнение проходило параллельно, возникает вопрос, насколько дорого конструирование FilmContext:. Если этот код выполняется быстро, то ваш начальный код был верен, но лучше бы переписать его в таком виде: static async Task Main(string[] args) { var t = DoSomething(); Console.WriteLine("Now u can type something"); Console.ReadLine(); if (!t.IsCompleted) Console.WriteLine("Waiting until task finishes..."); await t; } public static async Task DoSomething() { using (FilmContext context = new FilmContext()) { var c = await (from b in context.Films select b).ToListAsync(); foreach (var a in c) { Console.WriteLine(a.Descripton); } } } Если же new FilmContext выполняется медленно, то проще всего выгрузить весь DoSomething() на пул потоков: static async Task Main(string[] args) { var t = Task.Run(DoSomething); Console.WriteLine("Now u can type something"); Console.ReadLine(); if (!t.IsCompleted) Console.WriteLine("Waiting until task finishes..."); await t; }

Комментариев нет:

Отправить комментарий