У меня есть несколько методов async, которые делают вызовы httpclient другим серверам. Я хочу запустить их в конце вызова webapi и немедленно вернуться. Для каждого звонка необходимо записывать время, которое они берут, и когда ВСЕ завершены, мне нужно записать эти файлы в файл. Я потратил некоторое время на то, чтобы поработать, пока не получил его на работу, но я не знаю, почему он работает, а другие - нет.
Не могли бы вы рассказать об этом мне?
Вот основной способ, который не сработал. То есть, вызовы были сделаны, но LogTimeTaken не был (или, по крайней мере, не записывал файл журнала).
//inside webapi action
var tasks = new List<Task>
{
MakeCall1Async(data,timeTaken),
MakeCall2Async(data, timeTaken),
MakeCall3Async(data, timeTaken)
};
Task.Run(async () =>
{
await Task.WhenAll(tasks);
LogTimeTaken(timeTaken);
});
//finish webapi action and return
Вот как это работает:
//inside webapi action
Task.Run(async () =>
{
var tasks = new List<Task>
{
MakeCall1Async(data, timeTaken),
MakeCall2Async(data, timeTaken),
MakeCall3Async(data, timeTaken)
};
await Task.WhenAll(tasks).ContinueWith(t => LogTimeTaken(timeTaken));
});
//finish webapi action and return
Зачем?
Кроме того, я знаю о рисках использования огня и забывании внутри webapi, и что он не всегда заканчивается (например, когда пул приложений перерабатывается). 95% + достаточно хорош в этом случае.
РЕДАКТИРОВАТЬ
Я понимаю всех, кто относится к выбору технологии. Я могу перейти на архитектуру pub/sub или использовать QueueBackgroundWorkItem. Учитывая, что мне нужно только успешное завершение в 95% случаев, я думаю, что работать с ним, как и я, все равно. Реальный ответ, который я пытаюсь получить, - это то, почему первый путь выходит из строя, и второй путь удается записать в журнал.
Вы должны посмотреть на планировщики заданий, например, hangfire или Quartz.net
Ниже приведена хорошая запись в блоге по этим решениям.