2012-02-08 28 views
5

Tôi có một số tập tin được tạo ra trong một hàm định nghĩa là:Tệp có vẻ được mở sau khi được gửi dưới dạng tệp đính kèm của SmtpClient. Làm cách nào để xóa tệp?

Public Function GeneratePDF(exportFileName As String) As String 
    Dim GeneratePath As String = FileSystem.CombinePath(standardDirectory, exportFileName & DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") & ".pdf") 
    If GenerateFile(GeneratePath) Then 
     Return GeneratePath 
    End If 
    Return String.Empty 
End Function 

Những tập tin này ngay lập tức được in và các tập tin được tự động lưu vào một thư mục; bản thân các tập tin không được sử dụng bởi người dùng phần mềm thực tế. Tôi timestamp các tập tin để giữ cho chúng được xác định duy nhất cho mục đích kiểm toán.

Tôi hiện đã nhận được yêu cầu gửi một số tệp này qua email bên ngoài cho công ty và ai đó đã phàn nàn rằng tên tệp hiện tại không thân thiện với người dùng.

Vì vậy, tôi đã cố gắng sao chép các tập tin được tạo ra vào một thư mục tạm thời, với một tên thân thiện hơn, gửi email file thân thiện hơn, sau đó xóa nó, để lại dấu vết của tôi còn nguyên vẹn, như vậy:

Public Function GeneratePDF(exportFileName As String) As String 
    Dim GeneratePath As String = FileSystem.CombinePath(standardDirectory, exportFileName & DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") & ".pdf") 
    If GenerateFile(GeneratePath) Then 

     Dim friendlyFilePath As String = FileSystem.CombinePath(standardDirectory, GetFriendlyFileName(GeneratePath)) 
     System.IO.File.Copy(GeneratePath, friendlyFilePath) 

     Dim mailMsg As New System.Net.Mail.MailMessage 
     Dim smtp As New System.Net.Mail.SmtpClient 
     [Vast amount of code, which attaches friendlyFilePath to the email, then sends it] 

     System.IO.File.Delete(friendlyFilePath) 

     Return GeneratePath 
    End If 
    Return String.Empty 
End Function 

này ném một System.IO.IOException trên dòng System.IO.File.Delete(friendlyFilePath) vì tệp vẫn đang được sử dụng, sau khi tệp đã được gửi qua email.

Tôi đã lấy mã email, điều này làm cho quá trình sao chép và xóa hoạt động tốt, vì vậy dường như đính kèm tệp vào email gây ra sự cố.

Tôi cũng đã thử ngắt kết nối trước dòng xóa, chờ năm phút, xác nhận email đã được gửi, sau đó chuyển mã, nhưng ngoại lệ tương tự vẫn bị ném.

Có ai có thể đề xuất cách giải quyết vấn đề này không?

+0

Bất kỳ cơ hội nào trong khu vực [số lượng lớn mã] đó bạn có một luồng loại nào đó mà bạn chưa đóng? –

Trả lời

7

SmtpClient không giải phóng tay cầm vào phần đính kèm. Bạn sẽ phải xử lý thủ công, hoặc, những gì tôi làm, là sao chép nội dung tập tin vào MemoryStream trước. Mã bên dưới cũng sẽ hoạt động.

using (MailMessage message = new MailMessage(from, to, subject, body)) 
using (Attachment attachment = new Attachment(fileName)) 
{ 
    message.Attachments.Add(attachment); 
    mailClient.UseDefaultCredentials = true; 
    mailClient.Send(message); 
} 
+0

Yup. Xử lý thủ công tất cả các tệp đính kèm của thư sau khi nó được gửi đi. Đã giải quyết vấn đề. Cảm ơn. – Frosty840

3

Bạn nên sử dụng câu lệnh Sử dụng khi truy cập Tệp. Điều này sẽ định đoạt đối tượng của bạn và bạn sẽ có thể gọi System.IO.File.Delete của bạn()

thấy ở đây: http://msdn.microsoft.com/en-us/library/htd05whh(v=vs.80).aspx

+0

Đây là kết quả tốt hơn ... trừ khi bạn [vì bất kỳ lý do gì] không sử dụng như 'sử dụng' (sau đó sử dụng giải pháp @ Nasir) –

0

Bạn có đóng tập tin đính kèm của bạn sau khi bạn đã tạo ra nó?

System.IO.FileStream afile = System.IO.File.Create(@"c:\test\astream.csv"); 
afile.Close(); 
afile = null; 

Xem this forum câu hỏi tương tự đã được trả lời. (Đó là trong C# với asp.net, nhưng nó phải làm các trick khi chuyển đổi sang vb.net)

+0

Tệp đang bị xóa được tạo bằng cách sử dụng 'System.IO.File.Copy', vì vậy câu hỏi không áp dụng. – Frosty840

11

sau mailClient.Send(message); thêm message.Attachments.Dispose();

này sẽ giải phóng tài nguyên tập tin đính kèm

1

Trong khi tôi nhận ra bài cuối cùng về bài viết này cách đây vài năm, tôi nghĩ nó đáng giá thêm một lượng nhỏ thông tin bổ sung cho bất kỳ ai không biết ...

Nếu bạn gửi email không đồng bộ thì bạn không thể sử dụng "sử dụng" hoặc vứt bỏ bất cứ thứ gì cho đến khi cuộc gọi lại kích hoạt, thay vào đó bạn nên gửi cho MailMessage s tham số UserState của SendAsync(). Bằng cách đó, khi gọi lại, bạn sẽ có thể xử lý bất kỳ tệp đính kèm nào và cá thể MailMessage. Bạn cũng có thể vứt bỏ Mail Client vì nó sẽ là đối tượng người gửi.

Các vấn đề liên quan