System.ObjectDisposedException: 无法访问已释放的对象。对象名称:'System.Net.Sockets.NetworkStream'。使用 HttpClient

System.ObjectDisposedException: Cannot access a disposed object. Object name: 'System.Net.Sockets.NetworkStream'. With HttpClient

我需要并行发送多个 Post 请求。为此,我将使用以下代码:

        try
        {
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"key={customer.FCMServerKey}");

                var obj = new
                {
                    to = customer.FcmRegistrationId,
                    notification = new
                    {
                        title = push.PushTitle,
                        body = push.PushBody,
                    }
                };

                string json = JsonConvert.SerializeObject(obj);
                var data = new StringContent(json, Encoding.UTF8, "application/json");

                responseTasks.Add( client.PostAsync("https://fcm.googleapis.com/fcm/send", data));
                pushes.Add(push);
            }
        }
        catch (HttpRequestException ex)
        {

            Console.WriteLine("\nException with pushing!");
            Console.WriteLine("Message :{0} ", ex.Message);
        }

    }

    var responses = await Task.WhenAll(responseTasks);

    var count = 0;
    foreach (var response in responses)
    {
        var responseBody = await response.Content.ReadAsStringAsync();

        pushes[count].FCMResponse = responseBody;
        pushes[count].Sent = response.IsSuccessStatusCode;

        Console.WriteLine("FCM response:");
        Console.WriteLine(pushes[count].FCMResponse);

        count++;
    }

    await _pushRepository.SaveAsync(pushes);
}

如您所见,我将我的任务对象放入 responseTasks。然后我将借助此行发送所有请求:

var responses = await Task.WhenAll(responseTasks);

结果我有这个例外:

Unhandled Exception: System.Threading.Tasks.TaskCanceledException: The operation was canceled. ---> System.ObjectDisposedException: Cannot access a disposed object. Object name: 'System.Net.Sockets.NetworkStream'. at System.Net.Sockets.NetworkStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 size, CancellationToken cancellationToken) at System.IO.Stream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.Security.SslStream.BeginAuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions, CancellationToken cancellationToken, AsyncCallback asyncCallback, Object asyncState) at System.Net.Security.SslStream.<>c.b__47_0(SslClientAuthenticationOptions arg1, CancellationToken arg2, AsyncCallback callback, Object state) at System.Threading.Tasks.TaskFactory1.FromAsyncImpl[TArg1,TArg2](Func5 beginMethod, Func2 endFunction, Action1 endAction, TArg1 arg1, TArg2 arg2, Object state, TaskCreationOptions creationOptions) at System.Threading.Tasks.TaskFactory.FromAsync[TArg1,TArg2](Func5 beginMethod, Action1 endMethod, TArg1 arg1, TArg2 arg2, Object state, TaskCreationOptions creationOptions) at System.Threading.Tasks.TaskFactory.FromAsync[TArg1,TArg2](Func5 beginMethod, Action1 endMethod, TArg1 arg1, TArg2 arg2, Object state) at System.Net.Security.SslStream.AuthenticateAsClientAsync(SslClientAuthenticationOptions sslClientAuthenticationOptions, CancellationToken cancellationToken) at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken) --- End of inner exception stack trace --- at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)

怎么了?

请检查使用方法: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement

在您的代码中,client 将在 using 块结束后立即处理,但您在 responseTasks 列表中仍有待处理的任务将尝试访问它。您需要在 client 中使用 block.

获取结果