0

У меня есть два метода возвращающие 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(&quot;Готово&quot;);
Console.ReadKey();

}

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

mozay
  • 1

1 Answers1

1

Ваш код не работает потому, что

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);
rotabor
  • 4,251
  • Хотелось бы пояснение, почему код автора не работает. | ЗЫ: Task.Run рулит. – Alexander Petrov Oct 24 '23 at 18:07
  • @AlexanderPetrov А вот некоторые https://ru.stackoverflow.com/questions/1547441/%d0%9e%d1%88%d0%b8%d0%b1%d0%ba%d0%b0-%d0%bf%d1%80%d0%b8-%d0%b2%d0%bd%d0%b5%d1%81%d0%b5%d0%bd%d0%b8%d0%b8-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d0%b2-%d1%82%d0%b0%d0%b1%d0%bb%d0%b8%d1%86%d1%83-sqlite/1547448#1547448 не объясняют, и даже не отвечают на вопрос, и ничего... :-) – rotabor Oct 24 '23 at 18:14