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](Func
5 beginMethod, Func2 endFunction, Action
1 endAction, TArg1 arg1, TArg2 arg2, Object state, TaskCreationOptions creationOptions)
at System.Threading.Tasks.TaskFactory.FromAsync[TArg1,TArg2](Func5 beginMethod, Action
1 endMethod, TArg1 arg1, TArg2 arg2, Object state, TaskCreationOptions creationOptions)
at System.Threading.Tasks.TaskFactory.FromAsync[TArg1,TArg2](Func5 beginMethod, Action
1 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.
获取结果
我需要并行发送多个 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.TaskFactory
1.FromAsyncImpl[TArg1,TArg2](Func
5 beginMethod, Func2 endFunction, Action
1 endAction, TArg1 arg1, TArg2 arg2, Object state, TaskCreationOptions creationOptions) at System.Threading.Tasks.TaskFactory.FromAsync[TArg1,TArg2](Func5 beginMethod, Action
1 endMethod, TArg1 arg1, TArg2 arg2, Object state, TaskCreationOptions creationOptions) at System.Threading.Tasks.TaskFactory.FromAsync[TArg1,TArg2](Func5 beginMethod, Action
1 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.