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

.NET Core WPF:后台任务失败时非阻塞显示详情窗口的方案

WPF异步加载任务与异常处理的正确实现

核心改造思路

将按钮点击事件改为异步方法,利用async/await语法在不阻塞UI线程的前提下执行后台任务,同时正常捕获异常并弹出失败窗口。WPF允许事件处理程序使用async void(这是少数合法场景),配合await可自动回到UI上下文,无需额外Dispatcher操作。

修改后的代码实现

Launch.xaml.cs

// 将方法改为async void,适配WPF事件处理
private async void btnDemo_click(object sender, EventArgs e)
{
    ProgressBarVisibility = Visibility.Visible;
    // UI会立即更新,不再被后续代码阻塞

    try
    {
        // 如果LoadConfigs是耗时操作,同样包装到Task.Run中异步执行
        await Task.Run(() => LoadConfigs());
        
        // 异步执行耗时的COM+数据请求,释放UI线程处理进度条动画
        await Task.Run(() => PreCacheEHRData());
        
        // 加载成功,启动主应用
        LaunchMainApp();
    }
    catch (Exception ex)
    {
        // 回到UI上下文,弹出失败窗口(此时进度条窗口仍保持显示)
        var failureWindow = new FailureDetailsWindow();
        failureWindow.SetErrorInfo($"任务失败:{ex.Message}"); // 自定义错误信息展示逻辑
        failureWindow.ShowDialog();

        // 根据用户选择执行对应操作
        if (failureWindow.IsRetrySelected)
        {
            // 重试加载逻辑
            btnDemo_click(sender, e);
        }
        else
        {
            Close(ExitReasons.DATALOADERROR);
        }
    }
}

关键细节说明

  1. 异步任务执行:用await Task.Run()将同步耗时任务转移到后台线程,UI线程在await期间可正常处理进度条动画和其他UI交互。
  2. 异常捕获:await会将后台任务的异常抛回UI线程的try/catch块,无需额外处理跨线程异常。
  3. UI上下文自动切换:await完成后会自动回到UI线程,因此在catch中可直接创建并显示失败窗口,无需调用Dispatcher.Invoke。
  4. 加载窗口显示优化:如果需要进度条窗口全程保持显示,需确保其以非模态方式打开(使用Show()而非ShowDialog()),避免阻塞后续异步逻辑。

额外优化建议

  • 如果COM+服务提供原生异步调用方法,优先使用原生异步API替代Task.Run包装同步方法,提升性能和资源利用率。
  • 可将加载逻辑封装为独立的异步服务类,降低UI代码与业务逻辑的耦合度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 20:05:30