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

打开并返回子WPF应用后,父WPF应用因资源不足恢复报错

问题分析与解决方案

核心原因

  1. 主UI线程阻塞:原代码用DBAPP.WaitForExit()同步阻塞主应用的UI线程,长时间等待期间UI线程无法处理系统消息,可能导致窗口资源状态异常,关闭子应用后操作窗口属性时触发配额不足。
  2. 子应用资源泄漏:子应用运行3-5分钟后出现问题,大概率是数据库连接、GDI句柄或用户对象未正确释放,导致系统资源配额耗尽,影响主应用的窗口操作。

解决方案

1. 异步等待子应用退出,避免阻塞主UI线程

同步等待会让主窗口UI线程僵死,改用异步方式或事件监听,保证UI线程正常处理消息:

方式1:使用异步/await

private async void OpenDatabase(object sender, RoutedEventArgs e)
{
    ShowInTaskbar = false;
    Process DBAPP = new Process();
    DBAPP.StartInfo.FileName = "path/to/DBAPP.exe";
    DBAPP.EnableRaisingEvents = true;

    // 用Task包装Exited事件实现异步等待
    var exitCompletionSource = new TaskCompletionSource<bool>();
    DBAPP.Exited += (s, args) => exitCompletionSource.SetResult(true);

    DBAPP.Start();
    await exitCompletionSource.Task; // 异步等待,不阻塞UI线程

    // 回到UI线程设置属性(await后默认在原上下文)
    ShowInTaskbar = true;
}

方式2:注册Exited事件回调

private void OpenDatabase(object sender, RoutedEventArgs e)
{
    ShowInTaskbar = false;
    Process DBAPP = new Process();
    DBAPP.StartInfo.FileName = "path/to/DBAPP.exe";
    DBAPP.EnableRaisingEvents = true;

    DBAPP.Exited += (s, args) =>
    {
        // 必须回到UI线程操作窗口属性
        Dispatcher.Invoke(() =>
        {
            ShowInTaskbar = true;
        });
    };

    DBAPP.Start();
}

2. 修复子应用的资源泄漏问题

数据库连接确保释放

使用using语句自动管理Access数据库连接(OleDbConnection),避免连接泄漏:

// 子应用中数据库操作示例
using (OleDbConnection conn = new OleDbConnection("你的Access连接字符串"))
{
    conn.Open();
    // 执行查询、更新等操作
} // 自动关闭并释放连接资源

优化子应用关闭逻辑

调整关闭顺序,先确保窗口资源释放再终止应用,避免残留资源:

private void CloseMainMenu(object sender, RoutedEventArgs e)
{
    // 先关闭窗口释放资源
    Close();
    // 延迟一点时间再终止应用,给资源回收留时间
    Task.Delay(50).ContinueWith(_ => Application.Current.Shutdown(), TaskScheduler.FromCurrentSynchronizationContext());
}

排查资源泄漏

打开任务管理器,切换到「详细信息」标签,添加「GDI对象」「用户对象」列,运行子应用观察计数:

  • 如果计数持续增长,说明存在资源泄漏,需要逐一排查窗口控件、绘图资源、文件流等是否未正确释放。

3. 容错处理主应用的窗口属性设置

如果资源回收有延迟,可添加异常捕获或延迟执行:

await Task.Delay(100); // 给系统100ms时间回收资源
try
{
    ShowInTaskbar = true;
}
catch (Win32Exception ex)
{
    // 记录日志,或重试一次
    System.Diagnostics.Debug.WriteLine($"设置任务栏显示失败: {ex.Message}");
    Dispatcher.InvokeAsync(() => ShowInTaskbar = true, DispatcherPriority.Background);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 00:07:34