winforms C# HttpWebRequest问题:基础连接已关闭:发送时发生意外错误

7xllpg7q  于 2023-06-06  发布在  C#
关注(0)|答案(1)|浏览(456)

我正在制作一个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
    }
}
ee7vknir

ee7vknir1#

您能否确认内部任务是否运行?在这一行插入一个断点,看看是否命中:

cs.Token.ThrowIfCancellationRequested()

我怀疑这可能是类似于当你的using块处理流编写器时,它也处理了流,这关闭了连接。我会更改visual studio中的异常设置,以在任何异常类型时中断,然后您可以进一步询问此异常。
另外,请告诉我你没有建立一个电子邮件僵尸网络!
以下是一些额外的未经请求的建议:
当一个方法接受一个IEnumerable时不要调用_tasks.ToArray(),它作为一个列表很好,这种转换只会降低应用程序的速度
为什么要创建多个CancellationTokenSource对象?你能不能只创建一个,然后把令牌传下去?
为什么使用匿名Task.Run委托转发任务?你有一个返回任务的函数,所以你不能把它添加到列表中吗?
通过这些更改:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
_tasks = new List<Task>();
CancellationTokenSource cs = new CancellationTokenSource();
    
foreach (var emailList in smalChunks)
{
    Task task = HandleEmailList(emailList, userData, cs);
    _tasks.Add(task);
}
await Task.WhenAll(_tasks).ConfigureAwait(false);

还要更改任务函数的签名

private async Task HandleEmailList(List<SorterResults> emailList, CancellationToken ct)

相关问题