我有一个名单,350个可下载的图像网址。通过运行多个任务,我一次性下载10张图片。但是在下载了N数量的图像后,我的代码突然抛出了以下异常。
异常:“发送请求时发生错误。” InnerException:“请求被中止:无法创建SSL/TLS安全通道。” System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task任务)\r\n在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task任务)\r\n在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n .
我创建了一个示例项目来重现此异常。我手里拿着两个测试用例。您可以从我的天空大道在这里下载正在运行的测试项目。右键单击文件HTTPClientTestCases1and2.zip并下载。
案例1:使用单个实例HttpClient进行所有图像下载.
在本例中,我使用相同的HttpClient向10个urls发送并行请求。在这种情况下,大多数情况下下载是成功的。在最后一次成功下载图像之后,等待至少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中实现并行下载机的最佳方法是什么。
发布于 2013-01-09 19:24:45
我运行了您的示例应用程序,只在几种场景中得到错误:
Could not create SSL/TLS secure channel in Windows 8 Metro App是在我使用HTTP调试代理(Fiddler)时。如果我不使用Fiddler (拦截所有HTTP(S)调用),那么下载就没有问题。我甚至快速地开始多次下载(通过在一秒钟内多次单击蓝色下载区域)。结果是下载了所有项目(除上文提到的404错误外)。这里是成功下载的屏幕截图(除了404)。这个屏幕截图正在运行测试用例#2 (HttpClient的多个实例)。我确实运行了测试用例#1 (HttpClient的单个实例),结果也是成功的。

总之,我没有看到你们正在经历的问题。我唯一能想到的就是让你从不同的机器或地点尝试一下你的应用程序。
https://stackoverflow.com/questions/14158069
复制相似问题