Работает ли данный код асинхронно? По идее, должен, но у меня почему-то основной поток блокируется.
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);
}
}
}
Ответ
Смотрите.
Вы хотите, чтобы вывод в функции 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;
}
Комментариев нет:
Отправить комментарий