我有一個350個可下載圖像URL的列表。通過運行多個任務,我一次下載10張圖像並行。但下載後N圖片數量突然我的代碼拋出以下異常。請求已中止:無法在Windows 8 Metro App中創建SSL/TLS安全通道
例外情況:「發送請求時發生錯誤。」
InnerException:「請求已中止:無法創建SSL/TLS 安全通道。」
堆棧跟蹤:「在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任務 任務)\ r \ n在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任務 任務)\ r \ n在 系統.Runtime.CompilerServices.TaskAwaiter`1.GetResult(個)\ r \ n ...
我創建了一個示例項目重現此異常。我有2個測試案例在我的手。你可以從My Sky Drive Here下載正在運行的測試項目。右鍵單擊文件HTTPClientTestCas es1and2.zip並下載。
案例1:使用單個實例HttpClient進行所有圖片下載。
在這種情況下,我使用相同的HttpClient向10個URL發送並行請求。在這種情況下,大部分時間下載都是成功的。上次成功下載圖像後,至少等待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中下面的函數檢查2箱子
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中實現並行下載器的最佳方式是什麼?
假設您的圖片託管在SSL位置是否正確? –
@chuex是的。例如,圖片託管在Facebook或Twitter服務器上。 – Somnath
不幸的是,我沒有一個帶有SSL站點的測試服務器來嘗試你的代碼。如果有幫助,我可以在非SSL測試服務器上運行代碼 - 在此(非SSL)情況下,它工作得很好。 –