Blazor Server中DisposeAsync释放IJSObjectReference时抛出JSDisconnectedException
正确释放Blazor Server中的IJSObjectReference
问题原因
IJSObjectReference.DisposeAsync() 本质是通过JS互操作通知浏览器端释放对应的模块引用。当页面刷新时,Blazor的电路已经断开并开始销毁,此时发起JS互操作调用自然会抛出JSDisconnectedException。
解决方案
方案1:捕获异常并忽略
在电路断开的场景下,浏览器已经卸载页面,JS端的模块资源会被自动回收,服务器端的module引用也会随着电路销毁被GC回收,不会造成内存泄漏。因此可以捕获该异常并忽略:
async ValueTask IAsyncDisposable.DisposeAsync() { if (module is not null) { try { await module.DisposeAsync(); } catch (Microsoft.JSInterop.JSDisconnectedException) { // 电路已断开,JS端资源已被浏览器回收,无需额外处理 } } }
方案2:检查电路连接状态后释放
通过注入的IJSRuntime判断电路是否处于连接状态,仅在连接时调用DisposeAsync:
首先在组件中注入IJSRuntime:
[Inject] private IJSRuntime JS { get; set; } = default!;
然后修改DisposeAsync实现:
async ValueTask IAsyncDisposable.DisposeAsync() { if (module is not null && JS is Microsoft.AspNetCore.Components.Server.Circuits.CircuitJSRuntime circuitJS && circuitJS.IsConnected) { await module.DisposeAsync(); } }
两种方案都能避免报错,同时保证在组件正常卸载(非页面刷新)的场景下正确释放资源,不会引发内存泄漏。
内容的提问来源于stack exchange,提问作者Regina Beahm
相关产品推荐
相关产品推荐

