我正在制作一个winforms应用程序,我想同时发送多个HttpWebRequest
到我的Https API URL(如20-30个请求),总请求不受限制。然而,经过一段随机时间后,我的Winforms
应用程序遇到了问题error: The underlying connection was closed: An unexpected error occurred on a send
我应该更改代码的哪些部分,以使我的应用程序正确有效地运行,并发送多个HttpWebRequest
请求而不会出现问题
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
_tasks = new List<Task>();
cancelSources = new List<CancellationTokenSource>();
foreach (var emailList in smalChunks)
{
CancellationTokenSource cs = new CancellationTokenSource();
Task task = Task.Run(async () =>
{
await HandleEmailList(emailList, userData, cs);
}, cs.Token);
_tasks.Add(task);
cancelSources.Add(cs);
}
await Task.WhenAll(_tasks.ToArray()).ConfigureAwait(false);
功能波纹管手柄HttpWebRequest
private async Task HandleEmailList(List<SorterResults> emailList, CancellationTokenSource cs)
{
try
{
ar sortUrl = $"http://localhost:5000/api/xxx";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(sortUrl);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync()))
{
var jsonData = JsonConvert.SerializeObject(emailList.ToArray());
var mailData = $"{{\"mails\":{jsonData}}}";
await streamWriter.WriteAsync(mailData);
}
APIResponseData responseResult;
var httpResponse = (HttpWebResponse)(await httpWebRequest.GetResponseAsync());
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = await streamReader.ReadToEndAsync();
responseResult = JsonConvert.DeserializeObject<APIResponseData>(result);
}
cs.Token.ThrowIfCancellationRequested();
}
catch (Exception ex)
{
//ex.Message: The underlying connection was closed: An unexpected error occurred on a send
}
}
1条答案
按热度按时间ee7vknir1#
您能否确认内部任务是否运行?在这一行插入一个断点,看看是否命中:
我怀疑这可能是类似于当你的using块处理流编写器时,它也处理了流,这关闭了连接。我会更改visual studio中的异常设置,以在任何异常类型时中断,然后您可以进一步询问此异常。
另外,请告诉我你没有建立一个电子邮件僵尸网络!
以下是一些额外的未经请求的建议:
当一个方法接受一个
IEnumerable
时不要调用_tasks.ToArray()
,它作为一个列表很好,这种转换只会降低应用程序的速度为什么要创建多个
CancellationTokenSource
对象?你能不能只创建一个,然后把令牌传下去?为什么使用匿名
Task.Run
委托转发任务?你有一个返回任务的函数,所以你不能把它添加到列表中吗?通过这些更改:
还要更改任务函数的签名