Как запустить два метода с возвращающий значением Task асинхронно(/одновременно/параллельно)
У меня есть два метода возвращающие Task, которые должны работать параллельно, один метод инкрементирует i, другой, при нажатии i на клавиатуре, отображает текущие значение:
static Task Method(ref int i, CancellationToken cancellationToken)
{
while (i < 2100000000)
{
if (cancellationToken.IsCancellationRequested)
{
break;
}
i++;
}
return Task.CompletedTask;
}
static Task Info(ref int i, CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
if (Console.KeyAvailable)
{
ConsoleKeyInfo keyInfo = Console.ReadKey();
if (keyInfo.Key == ConsoleKey.I)
{
Console.Clear();
Console.WriteLine(i);
}
if (keyInfo.Key == ConsoleKey.Q)
{
break;
}
}
}
return Task.CompletedTask;
}
я пытался их запустить в Main, но они запускаются синхронно:
static async Task Main()
{
int i = 0;
var cts = new CancellationTokenSource();
Task task1 = Method(ref i, cts.Token);
Task task2 = Info(ref i, cts.Token);
await task1;
cts.Cancel();
Console.WriteLine("Готово");
Console.ReadKey();
}
Подскажите, пожалуйста, что я не так сделал, и как же все-таки запустить данные методы параллельно?
Ответы (1 шт):
Автор решения: rotabor
→ Ссылка
Ваш код не работает потому, что
Task task1 = Method(ref i, cts.Token);
запускает Method и ждёт окончания его работы для того, чтобы присвоить результат его выполнения как задачи переменной слева.
Нужно сделать так:
var task1 = new Task(() => Method(ref i, cts.Token));
var task2 = new Task(() => Info(ref i, cts.Token));
task1.Start(); Console.WriteLine("task1");
task2.Start(); Console.WriteLine("task2");
Task.Delay(5000).Wait(); // это чтобы через 5 с полюбому закончилось
cts.Cancel();
Task.WaitAll(new Task[] { task1, task2 });
Можно убрать CancellationToken и заменить последние три строки на:
Task.WaitAny(new Task[] { task1, task2 }, 5000);
Можно и с таксраном (ой, опечатка, наверное):
var task1 = Task.Run(() => Method(ref i, cts.Token)); Console.WriteLine("task1");
var task2 = Task.Run(() => Info(ref i, cts.Token)); Console.WriteLine("task2");
Task.WaitAny(new Task[] { task1, task2 }, 5000);