private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
_timer.Stop();
_logic.AddLogToMainFileServerLogs("*********Метод распределения запущен из таймера.*********");
List<Task> tasks = new List<Task>();
foreach (var depot in _logic.Depots)
{
_logic.AddLogToMainFileServerLogs("*********РЦ " + depot.Code + " запущено в поток.*********");
Task task = Task.Run(() => _logic.DistributeTrucks(depot.Code));
tasks.Add(task);
//_= await _logic.DistributeTrucks(depot.Code);
}
Task.WaitAll(tasks.ToArray());
_logic.AddLogToMainFileServerLogs("*********Метод распределения из таймера отработал РЦ.*********");
_timer.Start();
}
Я хочу что бы метод DistributeTrucks выполнялся параллельно, но при этом запуск таймера должен происходить только тогда, когда все задачи выполняться.
Сейчас я вижу в логах следующее:
А хочу видеть:
Что не так делаю?
public async void DistributeTrucks(string depotCode)
async void технтчески невозможно ожидать, но возможно async Task.
public async Task DistributeTrucks(string depotCode)
Тогда строчку с таской можно поменять вот так
Task task = _logic.DistributeTrucks(depot.Code);
Еще подскажите, в данном случае, метод DistributeTrucks будет работать параллельно, правильно?
Технически это работает так: когда в внутри метода встречается первый await, асинхронная машина состояний позвращает ожидающий завершения метода Task в точку вызова. Код, размещенный до первого await будет выполнен синхронно как в самом обычном синхронном метода (уделяйте этому внииание при написании асинхронных методов, иначе можете ропасть в ситуацию, когда асинхронный метод блокирует вызывающий поток на некоторое время). То есть в этот момент переменная task будет добавлена в список и цикл продолжит выполение.
Следовательно одновременно может выполняться (ожидаться) несколько или даже много асинхронных ожиданий. Можно сказать, что это параллельно, да. Но технически это не так. Вы просто ожидаете список тасок WaitAll, которые внутри себя тоже что-то ждут, ну там где у вас await внутри метода DistributeTrucks, при ожидании код не выполняется, этим и отличается асинхронность от параллельности. По сути, можно выполнять одновременно кучу асинхронных вызовов, технически используя для выполнения кода всего один поток. А когда есть всего один поток, то о какой параллельности может быть речь, верно?
Говоря самым простым языком Thread поток - это выполнялка, а Task - это ожидалка. При том, ожидалка может ждать и завершения выполнения кода в отдельном потоке текущего приложения await Task.Run, и выполнения какой-то операции вне текущего компьютера, например ожидать ответа из сети await httpClient.GetStringAsync(). Во втором случае код выполняется на сервере, а вы просто ждете результат.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей