请求被中止:无法在Windows 8 Metro应用程序中创建SSL/TLS安全通道
我有一个350个可下载图像URL的列表。我通过运行多个任务一次并行下载10幅图像。但是在下载了大量图片后,我的代码突然抛出了以下异常 异常:“发送请求时出错。” InnerException:“请求被中止:无法创建SSL/TLS 安全通道。” StackTrace:“在 System.Runtime.CompilerServices.TaskWaiter.ThrowForNonSuccess(任务 任务)\r\n位于 System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)\r\n位于 System.Runtime.CompilerServices.TaskWaiter`1.GetResult()\r\n 我创建了一个示例项目来重现此异常。我手头有两个测试用例。您可以从下载运行的测试项目。右键单击文件httpclienttestcases1和2.zip并下载 案例1:使用单个实例HttpClient进行所有映像下载。 在本例中,我使用相同的HttpClient向10个URL发送并行请求。在本例中,下载大部分时间都是成功的。上次成功下载映像后,请等待至少40秒(最多1分40秒)为下一批发送下一个并行下载请求。由于此异常,一个映像肯定会失败。但是,在许多地方,它已编写并建议使用单个HttpClient来处理多个请求请求被中止:无法在Windows 8 Metro应用程序中创建SSL/TLS安全通道,ssl,windows-8,microsoft-metro,httpclient,Ssl,Windows 8,Microsoft Metro,Httpclient,我有一个350个可下载图像URL的列表。我通过运行多个任务一次并行下载10幅图像。但是在下载了大量图片后,我的代码突然抛出了以下异常 异常:“发送请求时出错。” InnerException:“请求被中止:无法创建SSL/TLS 安全通道。” StackTrace:“在 System.Runtime.CompilerServices.TaskWaiter.ThrowForNonSuccess(任务 任务)\r\n位于 System.Runtime.CompilerServices.TaskWai
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);
});
}
}
private void Send10DownloadRequestParallel()
{
对于(Int32索引=0;索引<10;索引++)
{
Task.Run(()=>
{
Int32 index1=rand.Next(0,myImageDownloader.ImageURLs.Count-1);
UpdateDownloadProgress();
//案例1:使用单一共享HttpClient下载
//myImageDownloader.DownloadeUsingSingleSharedHTTPClient(index1);
//或
//案例2:每次使用创建Http客户端下载
myImageDownloader.creatingHttpClientEverytime(index1)下载;
});
}
}
我的问题:我做错了什么?通过克服此异常,在WinRT中实现并行下载程序的最佳方法是什么。我运行了您的示例应用程序,仅在几个场景中出现错误:
async void myImageDownloader_OnFailed(object sender, EventArgs e)
{
await App.CurrentDispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, delegate
{
TimeSpan time =(DateTime.Now -dateTimeSuccess);
String timeGap = "Ideal For:" + time.ToString() + "\n";
ErrorListBox.Text += "\n Failed When: " + DownloadInfo.Text + "\n";
ErrorListBox.Text += timeGap;
// CX - added null check for InnerException, as these are NULL on HTTP result status 404
var ex = sender as Exception;
if (ex.InnerException != null)
ErrorListBox.Text += ex.InnerException.Message;
else
ErrorListBox.Text += "Inner Exception null - Outer = (" + ex.ToString() + ")";
});
}
无法在Windows 8 Metro应用程序中创建SSL/TLS安全通道,是在我使用HTTP调试代理(Fiddler)时。如果我没有使用Fiddler,它会截获所有HTTP(S)调用,那么我下载时没有问题。我甚至连续快速启动了多次下载(在一秒钟内多次单击蓝色下载区域)。结果是所有项目都已下载(除了上面提到的404错误)
简而言之,我没有看到您遇到的问题。我唯一能想到的是您可以从不同的机器或位置尝试您的应用程序。假设您的图像托管在SSL位置下是否正确?@chuex是。例如,图像托管在Facebook或twitter服务器上。不幸的是,我没有测试服务器上有一个SSL站点可以尝试您的代码。如果有帮助,我可以在一个非SSL测试服务器上运行您的代码-在这种(非SSL)情况下运行得很好。@chuex,您可以尝试此链接。我使用您的SSL链接尝试了代码,一切都对我有效。下面是一些下载的示例代码(20次)您基于SSL的映像代码所做的全部工作是创建5次下载(一次),然后等待这5次下载完成。它会重复此操作,直到所有文件下载完成。+1,哪个Url引发异常404?您可以共享该Url吗?您可以在浏览器中尝试该Url,看看它是否引发404。@Somnath-我这次只能得到一个(可能有,也可能没有):我在浏览器中尝试了,但没有找到。你真的应该用谷歌
Fiddler proxy
。它在这些场景中非常方便,因为它显示了正在发出的请求,以及哪些请求成功或失败。