8 Stimmen

Die Datei scheint offen zu bleiben, nachdem sie von SmtpClient als Anhang gesendet wurde. Wie kann ich die Datei löschen?

Ich habe eine Reihe von Dateien, die in einer Funktion erzeugt werden, die wie folgt definiert ist:

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

Diese Dateien werden sofort gedruckt, und die Dateien werden automatisch in einem Verzeichnis gespeichert; die Dateien selbst sind nicht zur Verwendung durch die eigentlichen Softwarebenutzer bestimmt. Ich versehe die Dateien mit einem Zeitstempel, damit sie zu Prüfzwecken eindeutig identifiziert werden können.

Ich habe nun die Anforderung erhalten, einige dieser Dateien per E-Mail an das Unternehmen zu senden, und jemand hat sich beschwert, dass die derzeitigen Dateinamen nicht benutzerfreundlich sind.

Ich habe also versucht, die erzeugte Datei in ein temporäres Verzeichnis mit einem freundlicheren Namen zu kopieren, die freundlichere Datei per E-Mail zu versenden und sie dann zu löschen, wobei mein Prüfpfad intakt blieb, etwa so:

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

Dies führt zu einer System.IO.IOException auf der Linie System.IO.File.Delete(friendlyFilePath) weil die Datei nach dem Versand per E-Mail noch in Gebrauch ist.

Ich habe den E-Mail-Code herausgenommen, so dass das Kopieren und Löschen problemlos funktioniert.

Ich habe auch versucht, vor der Löschzeile einen Haltepunkt zu setzen, fünf Minuten zu warten, zu bestätigen, dass die E-Mail gesendet wurde, und dann den Code fortzusetzen, aber die gleiche Ausnahme wird immer noch ausgelöst.

Kann jemand einen Vorschlag machen, wie man dieses Problem lösen kann?

0 Stimmen

Besteht die Möglichkeit, dass Sie in der Region [Unmengen von Code] eine Art Stream haben, den Sie nicht geschlossen haben?

17voto

Nasir Punkte 171

Nach mailClient.Send(message); hinzufügen. message.Attachments.Dispose();

Dadurch werden die Ressourcen der Anlage freigegeben

8voto

Grant H. Punkte 3659

Der SmtpClient gibt den Handle für einen Anhang nicht frei. Sie müssen dies manuell tun, oder, was ich tue, kopieren Sie den Inhalt der Datei zuerst in einen MemoryStream. Der folgende Code sollte ebenfalls funktionieren.

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 Stimmen

Ja. Ich habe alle Anhänge der E-Mail-Nachricht nach dem Versand manuell entsorgt. Das Problem ist behoben. Danke!

3voto

Seany84 Punkte 5404

Sie sollten die Anweisung Using verwenden, wenn Sie auf Dateien zugreifen. Dadurch wird Ihr Objekt entsorgt und Sie sollten in der Lage sein, Ihr System.IO.File.Delete() aufzurufen.

siehe hier: http://msdn.microsoft.com/en-us/library/htd05whh(v=vs.80).aspx

0 Stimmen

Dies ist das bessere Ergebnis... es sei denn, Sie verwenden [aus welchen Gründen auch immer] nicht die Option 'Verwenden' (dann verwenden Sie @Nasirs Lösung)

1voto

Jim Punkte 21

Mir ist klar, dass der letzte Beitrag zu diesem Artikel schon einige Jahre zurückliegt, aber ich dachte, es lohnt sich, ein paar zusätzliche Informationen für alle hinzuzufügen, die es noch nicht wissen...

Wenn Sie Ihre E-Mail asynchron senden, können Sie nicht "using" verwenden oder etwas entsorgen, bis der Callback ausgelöst wird. Stattdessen sollten Sie Ihre MailMessage-Instanz als UserState-Parameter von SendAsync() senden. Auf diese Weise können Sie, wenn der Callback ausgelöst wird, alle Anhänge und die MailMessage-Instanz entsorgen. Sie können auch den Mail-Client entsorgen, da er das Absenderobjekt sein wird.

0voto

Msonic Punkte 1456

Haben Sie Ihre Anhangsdatei geschlossen, nachdem Sie sie erstellt haben?

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

参照 dieses Forum wo eine ähnliche Frage bereits beantwortet wurde. (Es ist in C# mit asp.net, aber es sollte den Trick tun, wenn in vb.net konvertiert)

0 Stimmen

Die zu löschende Datei wird erstellt mit System.IO.File.Copy Ihre Frage ist also nicht zutreffend.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X