ASP.NET通用处理器上传文件持续出现请求超时问题
解决ASP.NET通用处理器上传视频到Azure Blob超时问题
针对你遇到的使用ASHX通用处理器上传视频时出现超时、TaskCanceledException的问题,以下是具体的排查和解决步骤:
1. 调整ASP.NET和IIS的请求限制
默认情况下,ASP.NET对请求大小和执行时间有严格限制,即使是小视频也可能触发超时:
- 在
web.config的<system.web>节点下添加/修改:
<httpRuntime maxRequestLength="1048576" executionTimeout="3600" />
(maxRequestLength单位是KB,这里设置为1GB;executionTimeout单位是秒,设置为1小时)
- 如果是IIS 7及以上,还需要在
<system.webServer>节点下配置:
<security> <requestFiltering> <requestLimits maxAllowedContentLength="1073741824" /> </requestFiltering> </security>
(maxAllowedContentLength单位是字节,对应1GB)
2. 改用异步方式上传Blob
同步上传会阻塞请求线程,容易触发超时。修改处理器代码为异步模式:
修改FileUploadHandler.ashx.cs:
using System.IO; using System.Threading.Tasks; using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; using Azure.Core; namespace WebApplication1 { public class FileUploadHandler : IHttpAsyncHandler, System.Web.SessionState.IRequiresSessionState { public async Task ProcessRequestAsync(HttpContext context) { if (context.Request.Files.Count > 0) { HttpPostedFile postedFile = context.Request.Files[0]; AzureBlob az = new AzureBlob(); await az.UploadAsync(postedFile); } // 返回响应,避免前端无意义等待 context.Response.ContentType = "application/json"; await context.Response.WriteAsync("{\"status\":\"success\"}"); } public class AzureBlob { private readonly BlobServiceClient _blobService; public AzureBlob() { // 配置客户端超时和重试策略 var clientOptions = new BlobClientOptions { Retry = { MaxRetries = 3, Mode = RetryMode.Exponential }, Transport = new HttpClientTransport(new HttpClient { Timeout = TimeSpan.FromMinutes(5) }) }; _blobService = new BlobServiceClient("MY_CONNECTION_STRING", clientOptions); } public async Task UploadAsync(HttpPostedFile file) { if (file.ContentLength <= 0) return; var fileName = Path.GetFileName(file.FileName); var blobContainer = _blobService.GetBlobContainerClient("my-container-name"); await blobContainer.CreateIfNotExistsAsync(); // 容器访问策略只需设置一次,无需每次上传都执行 // await blobContainer.SetAccessPolicyAsync(PublicAccessType.BlobContainer); var blobClient = blobContainer.GetBlobClient(fileName); // 设置分块上传选项,提升大文件上传稳定性 var uploadOptions = new BlobUploadOptions { TransferOptions = new StorageTransferOptions { MaximumTransferSize = 1024 * 1024 * 4, // 4MB分块 InitialTransferSize = 1024 * 1024 * 4 } }; // 异步上传,确保流读取位置正确 using (var stream = file.InputStream) { stream.Position = 0; await blobClient.UploadAsync(stream, uploadOptions); } var fileUrl = blobClient.Uri.AbsoluteUri; } } public bool IsReusable => false; } }
3. 优化前端AJAX请求
添加错误回调和超时设置,便于排查前端侧问题:
const file = document.getElementById("uploadVideoFile").files[0]; var fd = new FormData(); fd.append("file", file); $.ajax({ type: "post", url: "/FileUploadHandler.ashx", data: fd, dataType: "json", contentType: false, processData: false, cache: false, timeout: 300000, // 5分钟超时 success: function() { console.log("Video file was uploaded successfully."); }, error: function(xhr, status, error) { console.error("Upload failed:", status, error); alert("上传失败,请检查网络或文件大小"); } });
4. 其他排查点
- 测试服务器到Azure Blob存储的网络连通性,可使用Azure CLI命令直接在服务器上上传文件验证
- 检查服务器的磁盘IO、网络带宽,确认没有资源瓶颈
- 避免在上传逻辑中执行重复的容器配置操作(如重复设置访问策略)
内容的提问来源于stack exchange,提问作者Max Voisard
相关产品推荐
相关产品推荐

