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()
. Во втором случае код выполняется на сервере, а вы просто ждете результат.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
После создания объекта Excel не удается его закрыть: он также висит диспетчере задач:
От пользователя приходит некий код, и он сравнивается с форматом кода для каждой конкретной страны(он может быть разным), и если его можно...