Blazor WASM中Firefox“No .NET call dispatcher has been set”错误解决咨询
这个问题我之前也碰到过!核心原因是Firefox的资源加载/初始化时序比Chrome快,导致你的JavaScript在Blazor的.NET运行时完全准备好之前,就尝试调用DotNet.invokeMethodAsync了——Chrome刚好因为加载速度的差异避开了这个问题,所以没报错。
下面是一步步的修复方案,亲测有效:
1. 调整JavaScript文件的加载顺序
你现在把browser-resize.js放在了<head>里,而Blazor的核心运行时脚本blazor.webassembly.js在<body>末尾加载。这意味着你的resize监听脚本可能在Blazor初始化完成前就开始运行,触发resize事件时自然找不到.NET调用调度器。
修改你的Index文件,把browser-resize.js移到blazor.webassembly.js之后:
<body> <app>Loading...</app> <div id="blazor-error-ui"> An unhandled error- WHY щ(゚Д゚щ) <a href="" class="reload">Reload</a> <a class="dismiss"></a> </div> <script src="_framework/blazor.webassembly.js"></script> <script src="/Libs/InputFile/inputfile.js"></script> <!-- 把resize脚本移到这里,确保Blazor先初始化 --> <script src="/JavaScript/browser-resize.js"></script> </body>
2. 把Resize服务改为Singleton注册
你的BrowserResizeService用了静态_instance变量,但注册的是Scoped服务——这会导致每次新的Scoped实例创建时,都会覆盖全局的_instance,在多组件场景下很容易出问题。而且浏览器resize是全局事件,单例服务才是合理的选择:
在Program.cs里修改服务注册:
builder.Services.AddSingleton<BrowserResizeService>();
同时调整服务类的实例赋值逻辑,避免被多次覆盖:
public class BrowserResizeService { private readonly IJSRuntime _JSRuntime; public event Action OnResize; private static BrowserResizeService _instance = null; public BrowserResizeService(IJSRuntime js) { _JSRuntime = js; // 只在第一次创建实例时赋值 if (_instance == null) { _instance = this; } } // 其他代码保持不变... }
3. 在JS中添加初始化检查
为了保险起见,在调用DotNet方法前先确认运行时已经初始化:
var browserResize = { resized: function () { // 确保DotNet对象存在且可用 if (typeof DotNet !== 'undefined' && typeof DotNet.invokeMethodAsync === 'function') { DotNet.invokeMethodAsync("StudyMate.Client", 'OnBrowserResize'); } } }; window.addEventListener("resize", browserResize.resized);
4. 确保组件正确实现IDisposable
你的Razor页面里写了Dispose方法,但没有实现IDisposable接口——Blazor不会自动调用未实现接口的Dispose方法,这会导致组件销毁时无法取消事件订阅,可能引发内存泄漏或无效回调:
在页面顶部添加接口声明:
@page "/ManageChosenSubjects" @inject StudentService studentService @inject SubjectService subjectService @inject UserService userService @inject AuthenticationStateProvider AuthenticationStateProvider @inject BrowserResizeService ResizeService @implements IDisposable <!-- 加上这行 -->
这样Blazor就能在组件销毁时正确调用你的Dispose方法,清理事件订阅了。
这些修改应该能彻底解决Firefox里的错误,同时优化你的Resize服务的稳定性。
内容的提问来源于stack exchange,提问作者Skuffd

