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

.NET Core 6调用GetEmployeeByEmployeeNumber时出现连接关闭异常求助

问题原因及解决方案

核心问题

  1. async void方法误用:PopulatePDFDoc使用async void定义,ASP.NET Core无法跟踪这类异步操作的完成状态。当Index方法执行完毕返回View后,请求的Scoped依赖(如_ackContext)会被框架回收,此时PopulatePDFDoc内的异步查询仍在执行,就会触发"连接已关闭"的异常。
  2. 未等待异步操作完成:Index中调用PopulatePDFDoc()时未添加await,导致异步操作在后台执行时,请求上下文已被提前释放。

修复步骤

  1. 修改PopulatePDFDoc的返回类型:将async void改为async Task,让框架能跟踪异步操作状态:
public async Task PopulatePDFDoc()
{
    AckPackage.Data.PDFPopulate.DocPDF doc = new Data.PDFPopulate.DocPDF();
    EmployeeInfo employee = await _employeeService.GetEmployeeByEmployeeNumber(up.EmployeeId);
    // 此处添加PDF处理逻辑
}
  1. 在Index方法中等待异步操作:调用PopulatePDFDoc时加上await,确保异步操作完成前请求上下文不被释放:
public async Task<IActionResult> Index()
{
   EmployeeInfo employee = await _employeeService.GetEmployeeByEmployeeNumber(up.EmployeeId); 
   await PopulatePDFDoc();
   return View();
}

额外优化建议

GetEmployeeByEmployeeNumber方法可简化,避免两次查询数据库,直接获取最新的EmployeeInfo:

public async Task<EmployeeInfo?> GetEmployeeByEmployeeNumber(string employeeId)
{
    UserPrincipal up = utilities.UserADIdentity.GetADUserInfo(WindowsIdentity.GetCurrent().Name.ToString());

    var employee = await _ackContext.EmployeeInfos
        .Include(e => e.EmergencyInfos)
        .Where(e => e.EmployeeNumber == employeeId)
        .OrderByDescending(e => e.DateFormFilled)
        .FirstOrDefaultAsync();
        
    // 过滤EmergencyInfos,仅保留当前EmployeeInfo的关联数据
    if(employee != null)
    {
        employee.EmergencyInfos = employee.EmergencyInfos
            .Where(p => p.EmployeeInfoId == employee.EmployeeInfoId)
            .ToList();
    }
        
    return employee;
}

注意点

  • 确保_ackContext是Scoped生命周期注入(ASP.NET Core中DbContext默认配置),保证每个请求有独立的DbContext实例,在请求期间保持有效。
  • 非事件处理程序中禁止使用async void,业务逻辑的异步方法必须返回Task或Task<T>。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 20:40:29