Swagger文件上传调用OpenReadStream触发ObjectDisposedException问题
问题原因
你遇到的System.ObjectDisposedException是因为请求上下文被提前释放导致的:
- 控制器方法里用
Task.Run启动后台异步任务后立刻返回Accepted(),ASP.NET Core会判定请求处理完成,随即释放当前请求的所有资源,包括IFormFile关联的文件流和底层对象。 - 后台任务还在执行时,
formFile已经被销毁,此时调用OpenReadStream()或CopyToAsync()自然会触发已释放对象的异常。
解决方案
根据业务需求选择以下两种处理方式:
方式一:直接等待异步任务完成(推荐,适合不需要即时返回的场景)
去掉Task.Run,直接await处理方法,确保控制器在文件处理完成后再返回,保证formFile全程有效:
[HttpPost("UploadBlackList")] public async Task<IActionResult> UploadBlackList(IFormFile formFile) { try { using Proceso proceso = new Proceso(_log, _datos, _storage, _gdp, _client, _apiIag, _proxy); await proceso.UploadBlackList(formFile); return Accepted(); } catch (Exception err) { _log.LogError(err.Message); return BadRequest(); } }
方式二:先复制文件内容到独立存储(适合需要后台异步处理、即时返回的场景)
如果必须让客户端立刻收到响应,需要先把formFile的内容复制到脱离请求上下文的流(比如MemoryStream),再把这个流传给后台任务:
[HttpPost("UploadBlackList")] public IActionResult UploadBlackList(IFormFile formFile) { try { // 先把文件内容复制到内存流,脱离请求上下文 using var memoryStream = new MemoryStream(); formFile.CopyTo(memoryStream); memoryStream.Position = 0; // 重置流指针到开头 // 后台任务使用复制后的内存流 Task.Run(async () => { using Proceso proceso = new Proceso(_log, _datos, _storage, _gdp, _client, _apiIag, _proxy); // 注意:需要修改UploadBlackList方法,接受Stream类型参数而非IFormFile await proceso.UploadBlackList(memoryStream); }); return Accepted(); } catch (Exception err) { _log.LogError(err.Message); return BadRequest(); } }
同时要修改Proceso.UploadBlackList的方法签名,改为接受Stream类型参数,后续操作基于这个内存流处理。
内容的提问来源于stack exchange,提问作者Catalin Briscan
相关产品推荐
相关产品推荐

