.NET 4.8异步Web API文件下载仍阻塞UI上下文求助
ASP.NET Web API 文件下载阻塞主UI上下文问题
我有一个基于.NET 4.8的ASP.NET Web API异步方法,用于实现文件下载,响应头设置了Content-Disposition: attachment,所有可等待方法都已添加.ConfigureAwait(false)配置。
部分后端代码如下:
string contentType = null; long length = 0; using (var blobStream = await ProcessBlobStreamAsync(reqModel, (cType, len) => { contentType = cType; length = len; }, cancellationToken).ConfigureAwait(false)) { resp.Content = new StreamContent(blobStream); resp.Headers.AcceptRanges.Add("bytes"); resp.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = fileName }; resp.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType); resp.Content.Headers.ContentLength = length; resp.Headers.TransferEncodingChunked = true; } return resp;
前端通过打开新标签页调用该API进行下载:
const newWindow = window.open('', '_blank'); newWindow.location.href = url;
问题现象
即便使用新标签页(甚至iframe)发起下载,当我尝试在主ASP.NET MVC应用中进行导航操作时,整个应用会挂起直到下载完成——尽管Web API方法早已返回200响应,实际下载才刚刚开始。浏览器Network标签中没有任何后续操作的提示。
已尝试的方案
- 研究SynchronizationContext,怀疑ASP.NET限制同时执行方法,但无法理解具体原因;
- 移除所有
AuthorizeAttribute(仅测试用),问题仍存在; - 已切换为HTTP/2协议,问题依旧;
- 尝试用
fetch替代新标签页方案,不仅用户体验差,仍会阻塞UI; - 确认
ApiController注入对象为请求单例,不存在IoC阻塞问题; - 跨浏览器测试,其他浏览器在下载时同样会出现挂起情况;
- 测试下载其他网站的attachment文件,无此问题;
- 调试过程中没有代码执行阻塞的情况;
- 使用iframe下载,仍会阻塞UI。
疑问
真的没有解决办法吗?网络不佳的用户可能需要数小时才能完成下载,能否在下载过程中解除UI上下文的阻塞?这正是我使用"attachment"并在新标签页下载的初衷。
内容的提问来源于stack exchange,提问作者codeMonkey
相关产品推荐
相关产品推荐

