2012-02-08 8 views
5

Mam liczbę plików, które są generowane w zależności zdefiniowane jako:Plik wydaje się być otwarty po wysłaniu jako załącznik przez SmtpClient. Jak mogę usunąć plik?

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 

Pliki te są natychmiast drukowane i pliki są automatycznie zapisywane w katalogu; same pliki nie są przeznaczone do użytku przez rzeczywistych użytkowników oprogramowania. Mam znacznik czasu plików, aby zachować je w unikalny sposób do celów audytu.

Otrzymałem już wymaganie, aby wysłać niektóre z tych plików na zewnątrz firmy, a ktoś narzekał, że obecne nazwy plików nie są przyjazne dla użytkownika.

Tak, próbowałem kopiowanie wygenerowany plik do katalogu temp, z przyjazną nazwą, wysyłając do przyjaznego plik, a następnie usuwając go, pozostawiając moją ścieżkę audytu w stanie nienaruszonym, tak:

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 

To rzuca System.IO.IOException na linii System.IO.File.Delete(friendlyFilePath), ponieważ plik jest nadal używany, po wysłaniu go pocztą e-mail.

Wyjęłam kod e-mail, który powoduje, że praca kopiowania i usuwania jest dobra, więc najwyraźniej załącza plik do wiadomości e-mail, która powoduje problem.

Próbowałem także breakpointing przed linią usuwania, czekając pięć minut, potwierdzając wysłanie e-maila, a następnie przesuwając kod, ale ten sam wyjątek jest nadal zgłaszany.

Czy ktoś może sugerować, jak rozwiązać ten problem?

+0

Czy istnieje szansa, że ​​w tym regionie [Wielkie ilości kodu] masz jakiś strumień, którego nie zamknąłeś? –

Odpowiedz

7

SmtpClient nie zwalnia uchwytu do załącznika. Będziesz musiał obsłużyć to ręcznie lub, co robię, najpierw skopiować zawartość pliku do MemoryStream. Poniższy kod również powinien działać.

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. Ręczne usunięcie wszystkich załączników wiadomości e-mail po ich wysłaniu. Rozwiązać problem. Dzięki. – Frosty840

3

Powinieneś użyć instrukcji Using podczas uzyskiwania dostępu do plików. To wyrzucać obiektu i powinien być w stanie połączyć się z System.IO.File.Delete()

zobaczyć tutaj: http://msdn.microsoft.com/en-us/library/htd05whh(v=vs.80).aspx

+0

To jest lepszy wynik ... chyba że jesteś [z jakiegokolwiek powodu] nie używając jako "używania" (następnie użyj @ rozwiązania Nysira) –

0

Czy zamknięciu pliku załącznika po utworzeniu go?

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

Zobacz this forum, jeśli podobne pytanie zostało wysłuchane. (Jest w C# z ASP.NET, ale powinno załatwić sprawę po przekonwertowaniu do VB.NET)

+0

Usuwany plik jest tworzony przy użyciu 'System.IO.File.Copy', więc twoje pytanie nie dotyczy. – Frosty840

11

po mailClient.Send(message); dodać message.Attachments.Dispose();

Spowoduje to uwolnienie środków mocujących

1

Choć zdaję sobie sprawę ostatniego posta w tym artykule kilka lat temu pomyślałem, że warto dodać niewielką ilość dodatkowych informacji dla każdego, kto jest nieświadomy ...

Jeśli wysyłasz swój e-mail asynchronicznie, nie możesz użyć "używania" lub zbywania czegokolwiek do czasu uruchomienia wywołania zwrotnego, zamiast tego należy wysłać instancję MailMessage s parametr UserState funkcji SendAsync(). W ten sposób po uruchomieniu wywołania zwrotnego będziesz mógł pozbyć się wszelkich załączników i instancji MailMessage. Możesz także Zlikwidować klienta pocztowego, ponieważ będzie to obiekt nadawcy.

Powiązane problemy