.NET Core 6调用GetEmployeeByEmployeeNumber时出现连接关闭异常求助
问题原因及解决方案
核心问题
async void方法误用:PopulatePDFDoc使用async void定义,ASP.NET Core无法跟踪这类异步操作的完成状态。当Index方法执行完毕返回View后,请求的Scoped依赖(如_ackContext)会被框架回收,此时PopulatePDFDoc内的异步查询仍在执行,就会触发"连接已关闭"的异常。- 未等待异步操作完成:
Index中调用PopulatePDFDoc()时未添加await,导致异步操作在后台执行时,请求上下文已被提前释放。
修复步骤
- 修改
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处理逻辑 }
- 在
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
相关产品推荐
相关产品推荐

