Unable to read data from the transport connection System.IO.IOException
Есть задача - асинхронно распарсить данные, get запросов очень много, поэтому решил распараллелить вот таким образом.
await Task.Run(() =>
{
Parallel.ForEach(collection, (itemFrom) =>
{
foreach (var itemTo in collection)
{
List<ResponseModel> result = default;
try
{
result = (List<ResponseModel>)ParseByCurrencyAsync(itemFrom.Key, itemTo.Key).Result;
}
catch (Exception ex){ }
}
});
});
В результате получаю ошибку из заголовка темы, ну и вот это дело

Почитал информацию по данной ошибке, судя по всему истекает время ожидания ответа. Видимо очень много запросов и сервер их блокирует. Подскажите пожалуйста, есть ли какое то решение для данной задачи?
Ответы (1 шт):
Исключение возвращает метод ParseByCurrencyAsync, и показанный код здесь не при чем. Но это плохой код, технически и семантически. Вот хороший эквивалент:
var tasks = new List<Task<List<ResponseModel>>>();
foreach (var itemTo in collection)
{
tasks.Add(ParseByCurrencyAsync(itemFrom.Key, itemTo.Key));
}
List<ResponseModel>[] result = await Task.WhenAll(tasks);
Но я на вашем месте бы задумался над ограничением количества одновременно работающих запросов
Никогда не используйте .Result, его можно использовать только для завершенных задач, например пусть будет некий task типа Task<int>:
// ВОТ ТАК НЕЛЬЗЯ
int number = task.Result;
Этот код повесит текущий поток до окончания работы метода, то есть ровно так, как если бы вы выполняли просто синхронный код.
Другой пример
// вот так можно
await task;
int number = task.Result;
А проще
int number = await task;
Как видите, практической пользы от .Result никакой, но она иногда есть, вот рабочий пример, где я не знаю, синхронно завершился вызванный метод или асинхронно (да, такое тоже бывает):
if (!task.IsCompleted)
{
await task;
}
int number = task.Result;
Что-то вроде оптимизации, запускаю ожидание только если нужно. Но случай действительно редкий и большинство разработчиков, чтобы не путатья сделают проще int number = await task;, и я вам тоже советую использовать только await, и никак иначе.