You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI Android端ObjectDisposedException异常排查求助

排查.NET MAUI Android 14上长时间运行的ObjectDisposed异常(Microsoft.Maui.Platform.LayoutViewGroup)

针对你遇到的长时间运行后抛出的ObjectDisposed_Generic异常,结合你的应用场景,给出以下具体排查和修复方向:

  • 强制UI线程上下文更新
    SignalR回调、Popup触发的更新可能脱离UI线程,即便MAUI绑定默认会自动切换线程,长时间运行后仍可能出现上下文丢失。所有涉及UI绑定的属性或集合更新,必须确保在主线程执行:

    MainThread.BeginInvokeOnMainThread(() => {
        // 更新ChildListTabletDto的Status属性或ObservableCollection操作
    });
    

    尤其是Popup关闭后,其关联的Dispatcher可能已失效,直接更新共享集合极易触发已销毁视图的绑定操作。

  • 规避单例页面的生命周期风险
    虽然将HomePage注册为单例,但Android系统在后台内存紧张时,可能回收视图资源(如Layout ViewGroup),但单例实例不会被释放,导致ViewModel仍在更新已Disposed的视图控件。
    在HomePage中添加活跃状态标记,ViewModel更新前先检查页面状态:

    // HomePage代码
    protected override void OnAppearing() {
        base.OnAppearing();
        ViewModel.IsPageActive = true;
    }
    
    protected override void OnDisappearing() {
        base.OnDisappearing();
        ViewModel.IsPageActive = false;
    }
    
    // ViewModel更新逻辑
    if(IsPageActive) {
        // 执行属性或集合更新操作
    }
    
  • 优化ObservableCollection的更新方式
    静态ObservableCollection并非线程安全,长时间异步更新可能导致集合内部状态不一致,触发视图绑定到已释放的布局容器。
    避免直接修改集合子项的属性,而是通过替换整个项的方式触发绑定更新,确保CollectionView正确感知变化:

    var targetIndex = ChildList.IndexOf(targetChild);
    if(targetIndex != -1) {
        // 基于原对象创建新实例(若为记录类型可直接用with语法)
        var updatedChild = new ChildListTabletDto {
            // 复制原属性,替换Status
            Status = newStatus,
            Id = targetChild.Id,
            // 其他属性...
        };
        ChildList[targetIndex] = updatedChild;
    }
    
  • 清理无效事件订阅
    Android 14对后台应用内存限制更严格,长时间运行后未释放的订阅会导致视图无法被GC回收,最终触发Disposed异常:

    • 在HomePage的OnDisappearing中取消SignalR的事件订阅,OnAppearing时重新订阅,避免无效回调触发UI更新。
    • 若ViewModel与页面之间有自定义事件绑定,改用WeakEventManager替代普通事件,避免强引用导致视图泄漏。
  • 优化CollectionView布局复用
    复杂的ItemTemplate布局可能导致ViewGroup重复创建/销毁,长时间更新后出现无效视图引用:

    • 简化ItemTemplate的嵌套层级,减少不必要的布局容器。
    • 显式启用CollectionView的视图复用:
      <CollectionView RecyclingMode="Enabled">
          <!-- ItemTemplate内容 -->
      </CollectionView>
      
  • 捕获完整异常栈定位根源
    当前仅提供了异常开头信息,完整栈能精准定位触发异常的具体操作。添加全局异常捕获记录完整信息:

    // 在App.xaml.cs的OnStartup或构造函数中添加
    AppDomain.CurrentDomain.UnhandledException += (sender, args) => {
        // 将Exception.ToString()写入日志文件
    };
    
    TaskScheduler.UnobservedTaskException += (sender, args) => {
        // 记录未观察到的任务异常
        args.SetObserved();
    };
    

内容的提问来源于stack exchange,提问作者OverMars

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 00:45:00