Я запутался в сценарии асинхронного запроса (asp - net -core) - PullRequest
0 голосов
/ 12 апреля 2020

Я пытался смоделировать сценарий, что когда я запрашиваю свой API-сервис один раз, мне нужно выполнить 4 ограниченных ввода-вывода для различных внешних API или баз данных и т. Д. c. чтобы получить ответ на мой пример.

Я хочу запускать эти запросы одновременно с асинхронным и, если я получу отрицательный ответ (ноль для моего примера) на один из этих запросов, остановите все запросы, как только я получу отрицательный ответ на один из них.

Согласно моему примеру, запросы были запущены в одно и то же время, и даже если я получаю отрицательный ответ на один из запросов, мне приходится ждать, пока длинный запрос (task4) не завершится. Это значит, что я смог получить результат хотя бы за 40 секунд. Как я могу перестать работать излишне на 20 секунд, когда я получаю нулевой ответ от второго запроса (задачи 2) на 20-й секунде?

Если это возможно, как мне справиться с этим сценарием?

 public class HomeController : Controller
    {
       public async Task<string> SampleAsyncAction()
       {
          var task1 = DoSomeIOAsync(10000);
          var task2 = DoSomeIOAsync(20000);
          var task3 = DoSomeIOAsync(30000);
          var task4 = DoSomeIOAsync(40000);

          var result = await Task.WhenAll(task1, task2, task3, task4);

          if (result.Any(x=> x == null))
                return "Error occurred";
              return "Operation was done successfully in " + result.Sum().ToString() + "millisecond";
       }

       private int? DoSomeIO(int millisecond)
       {
          Thread.Sleep(millisecond);

          if (millisecond == 20000)
             return null;
          return (millisecond);
       }

       private async Task<int?> DoSomeIOAsync(int millisecond)
       {
          return await Task.Run(() => DoSomeIO(millisecond));
       }
    }

1 Ответ

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

Во-первых, только asyn c работа может быть отменена, и только если этот asyn c работа поддерживает отмену. Команда syn c, такая как Thread.Sleep, не может быть отменена, поэтому то, что вы пытаетесь сделать здесь, в принципе невозможно начать.

Task.Run - это не волшебная палочка c, которая делает syn c внезапно асин c. Все, что вы делаете с этим, запускает код syn c в новом потоке. Он все еще должен работать до завершения, и этот поток будет связан до тех пор, пока это не произойдет.

Предполагая, что вы на самом деле имеете дело с асинхронным c кодом, и , которые Код asyn c поддерживает отмену (как правило, принимает ли он CancellationToken параметр), тогда способ сделать то, что вы хотите, - это пользовательский CancellationTokenSource. Вы создаете экземпляр этого и передаете его как маркер отмены каждому методу asyn c. Затем вы ожидаете каждую операцию, и если одна из них завершается неудачей, вы отправляете отмену в CTS, что затем приводит к отмене любых операций, использующих этот токен отмены.

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