ABP v7.1 Blazor应用SocketsHttpHandler已释放对象报错求助
ABP v7.1 Blazor应用访问已释放对象(System.Net.Http.SocketsHttpHandler)问题修复
在浏览器中打开ABP v7.1 Blazor应用并登录后,可正常使用几分钟,但之后总会抛出无法访问已释放对象的错误,目前只能通过重启IIS上的Blazor应用临时解决。错误日志如下:
Error: Volo.Abp.Http.Client.AbpRemoteCallException: An error occurred during the ABP remote HTTP request. (Cannot access a disposed object. Object name: 'System.Net.Http.SocketsHttpHandler'.) See the inner exception for details. ---> System.ObjectDisposedException: Cannot access a disposed object. Object name: 'System.Net.Http.SocketsHttpHandler'. at System.Net.Http.SocketsHttpHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.<SendAsync>g__Core|5_0(HttpRequestMessage request, CancellationToken cancellationToken) at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.<SendAsync>g__Core|5_0(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync(ClientProxyRequestContext requestContext) --- End of inner exception stack trace --- at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync(ClientProxyRequestContext requestContext) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync[T](ClientProxyRequestContext requestContext) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync[T](String methodName, ClientProxyRequestTypeValue arguments) at Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ClientProxies.AbpApplicationConfigurationClientProxy.GetAsync(ApplicationConfigurationRequestOptions options) at Volo.Abp.AspNetCore.Mvc.Client.MvcCachedApplicationConfigurationClient.GetRemoteConfigurationAsync() at Volo.Abp.AspNetCore.Mvc.Client.MvcCachedApplicationConfigurationClient.<GetAsync>b__19_0() at Volo.Abp.Caching.DistributedCache`2.GetOrAddAsync(TCacheKey key, Func`1 factory, Func`1 optionsFactory, Nullable`1 hideErrors, Boolean considerUow, CancellationToken token) at Volo.Abp.AspNetCore.Mvc.Client.MvcCachedApplicationConfigurationClient.GetAsync() at Volo.Abp.AspNetCore.Mvc.Client.RemotePermissionChecker.IsGrantedAsync(String name) at Volo.Abp.AspNetCore.Mvc.Client.RemotePermissionChecker.IsGrantedAsync(ClaimsPrincipal claimsPrincipal, String name) at Volo.Abp.Authorization.PermissionRequirementHandler.HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) at Microsoft.AspNetCore.Authorization.AuthorizationHandler`1.HandleAsync(AuthorizationHandlerContext context) at Microsoft.AspNetCore.Authorization.DefaultAuthorizationService.AuthorizeAsync(ClaimsPrincipal user, Object resource, IEnumerable`1 requirements) at Microsoft.AspNetCore.Components.Authorization.AuthorizeViewCore.IsAuthorizedAsync(ClaimsPrincipal user) at Microsoft.AspNetCore.Components.Authorization.AuthorizeViewCore.OnParametersSetAsync() at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task) at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync() Blazor.BasicTheme.Global.0FC7E56DDD5146F5685D7C13F585CBC7.js:1:119202 [2024-09-05T13:53:10.139Z] Error: Volo.Abp.Http.Client.AbpRemoteCallException: An error occurred during the ABP remote HTTP request. (Cannot access a disposed object. Object name: 'System.Net.Http.SocketsHttpHandler'.) See the inner exception for details. ---> System.ObjectDisposedException: Cannot access a disposed object. Object name: 'System.Net.Http.SocketsHttpHandler'. at System.Net.Http.SocketsHttpHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.<SendAsync>g__Core|5_0(HttpRequestMessage request, CancellationToken cancellationToken) at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.<SendAsync>g__Core|5_0(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync(ClientProxyRequestContext requestContext) --- End of inner exception stack trace --- at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync(ClientProxyRequestContext requestContext) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync[T](ClientProxyRequestContext requestContext) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync[T](String methodName, ClientProxyRequestTypeValue arguments) at Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ClientProxies.AbpApplicationConfigurationClientProxy.GetAsync(ApplicationConfigurationRequestOptions options) at Volo.Abp.AspNetCore.Mvc.Client.MvcCachedApplicationConfigurationClient.GetRemoteConfigurationAsync() at Volo.Abp.AspNetCore.Mvc.Client.MvcCachedApplicationConfigurationClient.<GetAsync>b__19_0() at Volo.Abp.Caching.DistributedCache`2.GetOrAddAsync(TCacheKey key, Func`1 factory, Func`1 optionsFactory, Nullable`1 hideErrors, Boolean considerUow, CancellationToken token) at Volo.Abp.AspNetCore.Mvc.Client.MvcCachedApplicationConfigurationClient.GetAsync() at Volo.Abp.AspNetCore.Mvc.Client.RemotePermissionChecker.IsGrantedAsync(String name) at Volo.Abp.AspNetCore.Mvc.Client.RemotePermissionChecker.IsGrantedAsync(ClaimsPrincipal claimsPrincipal, String name) at Volo.Abp.Authorization.PermissionRequirementHandler.HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) at Microsoft.AspNetCore.Authorization.AuthorizationHandler`1.HandleAsync(AuthorizationHandlerContext context) at Microsoft.AspNetCore.Authorization.DefaultAuthorizationService.AuthorizeAsync(ClaimsPrincipal user, Object resource, IEnumerable`1 requirements) at Microsoft.AspNetCore.Components.Authorization.AuthorizeViewCore.IsAuthorizedAsync(ClaimsPrincipal user) at Microsoft.AspNetCore.Components.Authorization.AuthorizeViewCore.OnParametersSetAsync() at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
修复方案
调整HttpClient生命周期与连接池配置
在模块的ConfigureServices方法中显式配置HttpClient为单例,并延长连接池生命周期,避免Handler被提前释放:context.Services.AddHttpClient("AbpRemoteClient") .ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler { PooledConnectionLifetime = TimeSpan.FromMinutes(30), PooledConnectionIdleTimeout = TimeSpan.FromMinutes(10) });自定义缓存应用配置客户端
替换默认的MvcCachedApplicationConfigurationClient,使用IHttpClientFactory创建临时HttpClient实例,避免复用已释放的Handler:[Dependency(ReplaceServices = true)] public class CustomCachedApplicationConfigurationClient : MvcCachedApplicationConfigurationClient { private readonly IHttpClientFactory _httpClientFactory; private readonly IServiceProvider _serviceProvider; public CustomCachedApplicationConfigurationClient( IDistributedCache<ApplicationConfigurationDto> cache, IHttpClientFactory httpClientFactory, IOptions<AbpApplicationConfigurationClientOptions> options, IServiceProvider serviceProvider) : base(cache, httpClientFactory.CreateClient("AbpRemoteClient"), options) { _httpClientFactory = httpClientFactory; _serviceProvider = serviceProvider; } protected override async Task<ApplicationConfigurationDto> GetRemoteConfigurationAsync() { using var client = _httpClientFactory.CreateClient("AbpRemoteClient"); var proxy = new AbpApplicationConfigurationClientProxy(client, _serviceProvider); return await proxy.GetAsync(new ApplicationConfigurationRequestOptions()); } }禁用HttpClient Handler自动清理
在Program.cs中配置HttpClient工厂,禁止请求后自动释放Handler:builder.Services.AddHttpClient() .ConfigureHttpMessageHandlerBuilder(builder => { if (builder.PrimaryHandler is SocketsHttpHandler handler) { handler.DisposeHandlerAfterRequest = false; } });升级ABP补丁版本
将ABP相关NuGet包升级到v7.1.x系列的最新补丁版本,官方可能已修复此类资源释放的生命周期问题。
内容的提问来源于stack exchange,提问作者Hyppothalamus
相关产品推荐
相关产品推荐

