2016-12-07 2 views
1

Я использую .net HTTPClient для сохранения некоторых данных с помощью API POST REST. Размер полезной нагрузки для этого API составляет около 10 МБ. Я разделяю свои данные в кусках и называет этот POST API для каждого фрагмента. У меня вопрос в основном вокруг подхода:Запуск HttpClient POST параллельно

  1. Я планирую создать единый статический экземпляр HTTPClient и будет использовать один и тот же экземпляр для приложения. Какой должен быть мой подход? (создайте однопользовательский или новый клиент для каждого вызова POST API)

  2. Я хотел бы вызвать все эти вызовы POST-запроса параллельно (используя TASKS в .net). Есть ли способ остановить оставшиеся задачи, если какая-либо одна из задач завершилась неудачей. Я ищу пример кода.

    _factory = new TaskFactory(); 
    _factory.StartNew(() => 
          //Call to async POST API using HttpClient     
         ).ContinueWith((response) => 
           { 
            if (!response.IsFaulted) 
            { 
             //Do something 
            } 
            else { 
             this._logger.Error("log the error"); 
            } 
           }); 
    
+0

Может булева переменная, устанавливается истина/ложь. Другие задачи могут затем проверить эту переменную и при необходимости остановить. – SpiderPig

+0

Вы также можете сделать это с помощью токена отмены. Ниже приведен пример кода https://msdn.microsoft.com/en-us/library/dd321955(v=vs.110).aspx. Также HTTPClient имеет метод отмены всех ожидающих запросов. https://msdn.microsoft.com/en-us/library/system.net.http.httpclient.cancelpendingrequests(v=vs.118).aspx – SpiderPig

ответ

1
  1. Если ваши звонки все на одном хосте, использовать экземпляр общего HttpClient.

  2. Нет необходимости явно создавать задачи с использованием TaskFactory.StartNew, чтобы параллельно выполнять асинхронную работу с I/O-привязкой. Я бы предложил использовать Task.WhenAll. Что-то вроде этого:

    try { 
        await Task.WhenAll(chunks.Select(MakeCall)); 
    } 
    catch (Exception) { 
        _client.CancelPendingRequests(); 
    } 
    
    
    private async Task MakeCall(string chunk) { 
        var response = await _client.PostAsync(chunk); 
        if (!response.IsFaulted) { 
         //Do something 
        } 
        else { 
         this._logger.Error("log the error"); 
         throw new Exception("call failed!"); 
        } 
    } 
    
Смежные вопросы