У меня есть список 350 загружаемых URL-адресов изображений. Я загружаю 10 изображений параллельно одним выстрелом, запуская несколько задач. Но после загрузки N количества изображений внезапно мой код выдает следующее исключение.
Исключение: "Произошла ошибка при отправке запроса".
InnerException: "Запрос был прерван: не удалось создать SSL/TLS безопасный канал".
StackTrace: "at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task задача)\r\n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task задача)\r\n в System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n...
Я создал образец проекта, чтобы воспроизвести это исключение. В моей руке у меня 2 теста. Вы можете загрузить текущий тестовый проект из My Sky Drive Here. Щелкните правой кнопкой мыши файл HTTPClientTestCases1and2.zip и загрузите.
Случай 1: использование одного экземпляра HttpClient для загрузки всего изображения.
В этом случае я отправляю параллельный запрос на 10 URL-адресов, используя тот же HttpClient. В этом случае загрузка выполняется в большинстве случаев. После последней успешной загрузки изображения подождите минимум 40 секунд (максимум 1 минута 40 секунд), чтобы отправить следующий запрос параллельной загрузки для следующей партии. Из-за этого исключается одно изображение. Но так много мест написано и предложило использовать один HttpClient для множественного запроса.
   public async void DownloadUsingSingleSharedHttpClient(Int32 imageIndex)
    {   
        Uri url = new Uri(ImageURLs[imageIndex]);
        UnderDownloadCount++;
        try
        {
            Byte[] contentBytes = null;
            try
            {
                // Exception IS THROWN AT LINE BELOW 
                HttpResponseMessage response = await _httpClient.GetAsync(url);
                contentBytes = await response.Content.ReadAsByteArrayAsync();
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Download Failed at GetAsync() :" + ex.Message);
                throw ex;
            }
            DownloadedCount++;
            if (OnSuccess != null)
                OnSuccess(this, new DownloadSuccessEventArgs() { Index = imageIndex, Data = contentBytes });
        }
        catch (HttpRequestException hre)
        {
            DownloadFailedCount++;
            if (OnFailed != null)
                OnFailed(hre, null);
        }
        catch (TaskCanceledException hre)
        {   
            DownloadFailedCount++;
            if (OnFailed != null)
                OnFailed(hre, null);
        }
        catch (Exception e)
        {
            DownloadFailedCount++;
            if (OnFailed != null)
                OnFailed(e, null);
        }
    }
Случай 2: Создание нового экземпляра HttpClient для каждого изображения Загрузка
В этом случае он просто терпит неудачу очень часто из-за того же исключения при одновременном загрузке изображений.
public async void DownloadUsingCreatingHttpClientEveryTime(Int32 imageIndex)
{
    Uri url = new Uri(ImageURLs[imageIndex]);
    UnderDownloadCount++;
    try
    {
        Byte[] contentBytes = null;
        using (HttpClientHandler _handler = new HttpClientHandler())
        {
            _handler.AllowAutoRedirect = true;
            _handler.MaxAutomaticRedirections = 4;
            using (HttpClient httpClient = new HttpClient(_handler))
            {
                httpClient.DefaultRequestHeaders.ExpectContinue = false;
                httpClient.DefaultRequestHeaders.Add("Keep-Alive", "false");
                try
                {
                    // Exception IS THROWN AT LINE BELOW 
                    contentBytes = await httpClient.GetByteArrayAsync(url.OriginalString);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine("Download Failed :" + ex.Message);
                    throw ex;
                    }
                }
            _handler.Dispose();
        }
        DownloadedCount++;
        if (OnSuccess != null)
            OnSuccess(this, new DownloadSuccessEventArgs() { Index = imageIndex, Data = contentBytes });
    }
    catch (HttpRequestException hre)
    {
        DownloadFailedCount++;
        if (OnFailed != null)
            OnFailed(hre, null);
    }
    catch (TaskCanceledException hre)
    {
        DownloadFailedCount++;
        if (OnFailed != null)
            OnFailed(hre, null);
    }
    catch (Exception e)
    {
        DownloadFailedCount++;
        if (OnFailed != null)
            OnFailed(e, null);
    }
}
Пожалуйста, отредактируйте следующую функцию в MainPage.xaml.cs, чтобы проверить два случая
 private void Send10DownloadRequestParallel()
    {
        for (Int32 index = 0; index < 10; index++)
        {
            Task.Run(() =>
            {   
                Int32 index1 = rand.Next(0, myImageDownloader.ImageURLs.Count - 1);
                UpdateDownloadProgress();
                // Case 1: Download Using Single Shared HttpClient
                // myImageDownloader.DownloadUsingSingleSharedHttpClient(index1);
                // OR
                // Case 2: Download Using Creating Http Client Every Time
                myImageDownloader.DownloadUsingCreatingHttpClientEveryTime(index1);
            });
        }
    }
Мой вопрос: Что я делаю неправильно? Каков наилучший способ реализации параллельного загрузчика в WinRT, преодолев это исключение.

