MAUI中SignalR的HubConnection.Closed事件触发调用目标异常问题
问题成因分析
你的代码和事件定义存在几个关键问题,直接导致了这个“Exception has been thrown by the target of an invocation.”异常:
事件名称不匹配
你定义的事件是public event Action? Closed2;,但在SignalR的Closed事件处理逻辑里调用的是this.Closed?.Invoke(...)——这里的Closed并未被定义,当尝试触发一个不存在的事件委托时,就会引发目标调用异常。这是当前最直接的触发原因。UI操作跨线程风险
SignalR的Closed事件大概率在后台线程触发,直接调用Application.Current.MainPage.DisplayAlert属于跨线程访问UI控件,这类操作在MAUI中会引发异常,而该异常会被包装成“目标调用异常”抛出。异步事件处理的异常扩散
虽然你的代码返回了await Task.CompletedTask;,但如果后续修正事件名称后,Closed2的订阅者逻辑中存在未处理的异常,也会被包装成此类反射调用异常。
修复建议
- 修正事件名称:将代码中所有
this.Closed?.Invoke(...)替换为this.Closed2?.Invoke(...),确保调用的是你实际定义的事件。 - 确保UI操作在主线程执行:调用
DisplayAlert前切换到MAUI主线程,示例代码如下:MainThread.BeginInvokeOnMainThread(async () => { await Application.Current.MainPage.DisplayAlert("Error", "Connection closed with unknown error.", "Ok"); }); - 捕获订阅者异常:触发
Closed2事件时,建议添加异常捕获,避免订阅者的异常扩散影响SignalR连接逻辑:var closedHandler = this.Closed2; if (closedHandler != null) { try { closedHandler.Invoke(exception == null ? "Connection closed with unknown error." : $"Connection closed due to an error: {exception.Message}"); } catch (Exception ex) { // 记录或处理订阅者抛出的异常 } }
内容的提问来源于stack exchange,提问作者RUSHI HARDWARE
相关产品推荐
相关产品推荐

