Массовое чтение изображений из URL с использованием TPL (Task.WhenAll) заходит в тупик, когда WebClient выдает исключение тайм-аута - PullRequest
0 голосов
/ 25 января 2019

Я создал консольное приложение .net core 2.0, где я читаю данные изображений из URL-адресов и обрабатываю их. Поскольку изображения в большом количестве, я делаю в потоках. Все работает нормально, но когда изображения не возвращают никаких данных и выдают исключение тайм-аута, потоки зависают / зависают и продолжают работу. Кажется, это тупик, но я не знаю, где именно.

Ниже мой код.

int batchSize = 25;
int numberOfBatches = xmlProperties.Count() < batchSize ? 1 : ((((xmlProperties.Count() / batchSize) % 1) == 0) ? (xmlProperties.Count() / batchSize)
                                                                    : (xmlProperties.Count() / batchSize) + 1);
for (int i = 0; i < numberOfBatches; i++)
{
    Task[] Requests = xmlProperties
                        .Skip(i * batchSize)
                        .Take(batchSize)
                        .Select(l => UploadImage(l.PropertyRefNo, l.Images))
                        .ToArray();
    await Task.WhenAll(Requests); // does not return when UploadImage throws exception in WebClient request.
}

public async Task UploadImage(string PropertyRefNo, List<string> Images)
{
    Images = Images.OrderBy(x => x).Take(10).ToList();          

    var index1 = 0;
    foreach (var item in Images)
    {
        try
        {
            index1 = index1 + 1;
            using (MemoryStream imageStream = await ImageUtilities.GetImageData(item)) // Exception comes here in reading data from URL
            {
                // Do Rest Work
            }
        }
        catch (Exception ex)
        {
            await AddLog(0, JobStatus.ImageFailedFull.ToString(), ex.ToString(), PropertyRefNo + " : " + item, 0);
        }
    }
}

public static async Task<MemoryStream> GetImageData(string filename)
{
    try
    {
        using (HttpClient client = new HttpClient())
        {
            var data = await client.GetAsync(filename);
            byte[] imageStream = await data.Content.ReadAsByteArrayAsync();
            return new MemoryStream(imageStream);
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

public class WebClientWithTimeout : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest wr = base.GetWebRequest(address);
        wr.Timeout = 100000; // 100 seconds
        return wr;
    }
}

Любая помощь будет принята с благодарностью.

...