. NET Правильное использование задания - PullRequest
1 голос
/ 06 апреля 2020

Я новичок в. NET Задачи и асинхронное c кодирование, поэтому я просто хотел бы знать, что я должен делать в моем случае:

У меня есть. NET Core WebApi, который получает файл XML, который служит триггером для следующего процесса:

  1. Мне нужно, чтобы процесс выполнялся в "фоновом режиме", поэтому я имею в виду, что вызывающая сторона API должна немедленно получить ответ и затем процесс должен запускаться
  2. Мне нужно проанализировать XML для объекта
  3. С этими данными мне нужно связаться с 3 API
  4. Если какой-либо из этих API не отвечает или не может получить необходимые данные, нам нужно остановить и записать это
  5. Если все данные получены, мне нужно выполнить расчет с этими данными (получить некоторые данные из базы данных и рассчитать с API и данными базы данных)
  6. Когда расчет будет завершен, мне нужно отправить электронное письмо и связаться с другим API

    7. И самое главное: я в безопасности с этим из-за AppRecycle?

Это просто для того, чтобы объяснить мою ситуацию, поэтому у меня есть следующее:

[HttpPost]
public async Task<JsonResult> DepositAsync([FromBody] Taa message){
try
{
    Api1Response api1Response = await this.GetApiData1();
    Api1Response api2Response = await this.GetApiData2();

    // If all of this was successful, do the calculation
    CalculationResult result = await this.CalculateAsync(api1Response, api2Response);

    // Notify 
    await Notify(result);
}
catch (Exception ex)
{
    Log.Error($"Something went wrong: {ex.Message}", ex);
    throw;
}


return new JsonResult(new ApiResponse<string>(requestId.ToString(), Response, StatusCodes.Status200OK) { Data = "Success" });
}

Вопрос, который у меня сейчас есть:

  1. Когда мне нужно использовать Task.Run (() => {}); Внутри методов GetApiData1 (), GetApiData2 (), чтобы выполнить вызов Http?
  2. Нужно ли вызывать методы GetApi внутри Task.Run (() => {}); ?
  3. В общем, когда мне нужно использовать Task.Run, а когда нет?

Или мне просто нужно сделать это:

[HttpPost]
public async Task<JsonResult> DepositAsync([FromBody] Taa message){
try
{
    Task.Run(() => {
        Api1Response api1Response = await this.GetApiData1();
        Api1Response api2Response = await this.GetApiData2();

        // If all of this was successful, do the calculation
        CalculationResult result = await this.CalculateAsync(api1Response, api2Response);

        // Notify 
        await Notify(result);
    });  
}
catch (Exception ex)
{
    Log.Error($"Something went wrong: {ex.Message}", ex);
    throw;
}


return new JsonResult(new ApiResponse<string>(requestId.ToString(), Response, StatusCodes.Status200OK) { Data = "Success" });
}

Большое спасибо!

1 Ответ

1 голос
/ 06 апреля 2020

Правильно, что вы можете использовать Task.Run без await, чтобы "переложить" некоторую работу в другой поток из ThreadPool. При этом время ответа на ваш запрос не будет зависеть от работы, выполняемой внутри него.

Однако любое исключение, которое происходит внутри этой функции, не будет выброшено в поток вызывающий (так как вызов не ожидается). Это фактически означает, что ваш блок try-catch будет перехватывать только те исключения, которые возникают при создании нового Task (методом Task.Run). Другими словами, он не будет отлавливать ошибки, возникающие при обработке лямбды, передаваемой методу Task.Run.

Таким образом, в вашем случае второй подход будет правильным (с упомянутыми недостатками выше). Кроме того, IIS будет ожидать завершения работы потоков до sh и выхода при утилизации , ограниченный временем ожидания, установленным в пуле потоков. Таким образом, если выполнение превысит время ожидания, поток будет принудительно уничтожен.

Наконец, в. Net Введены основные новые типы служб, которые называются размещенными службами и реализуют IHostedService * 1018. *. Они созданы для поддержки подобных долгосрочных фоновых задач. Вы можете ознакомиться с ними через официальную документацию , и это будет моя рекомендация.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...