#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; }
Комментариев нет:
Отправить комментарий