ASP.NET上传附件发邮件时SaveAs方法报进程占用IOException错误
问题根因分析
- 资源未主动释放导致文件锁残留
代码中用到的MailMessage(即变量mail)、Attachment、SmtpClient(即变量objClient)都属于实现了IDisposable接口的类型,会持有附件文件的非托管句柄。你没有主动释放这些对象的资源,也没有用using块自动回收,文件锁会等到GC随机回收时才会解除。如果有重复上传同名文件的请求,第二次执行SaveAs操作时,前一次请求残留的文件锁还未释放,就会抛出文件被占用的IO异常。 - 文件名冲突
你直接使用上传文件的原始文件名保存在服务器同一目录下,多个用户上传同名文件时,SaveAs操作会尝试覆盖已有文件,如果已有文件正被其他请求占用,也会触发该报错。
修复方案
- 所有实现
IDisposable的邮件相关对象都用using块包裹,执行完成后自动释放资源,即时解除文件锁。 - 保存文件时生成唯一文件名,避免同名冲突。
修复后参考代码
if (inpAttachment1.PostedFile != null) { HttpPostedFile attFile = inpAttachment1.PostedFile; int attachFileLength = attFile.ContentLength; string fullFilePath = null; if (attachFileLength > 0) { // 生成全局唯一文件名避免冲突 string rawFileName = Path.GetFileName(inpAttachment1.PostedFile.FileName); strFileName = $"{Guid.NewGuid():N}_{rawFileName}"; fullFilePath = Server.MapPath(strFileName); inpAttachment1.PostedFile.SaveAs(fullFilePath); // using块包裹所有IDisposable对象,自动释放资源 using (Attachment attach = new Attachment(fullFilePath)) { mail.Attachments.Add(attach); attach1 = strFileName; using (objClient) { objClient.Send(mail); } } } // 所有资源释放后再执行删除操作 if (attach1 != null && File.Exists(fullFilePath)) File.Delete(fullFilePath); }
内容的提问来源于stack exchange,提问作者user2501777
相关产品推荐
相关产品推荐

