2012-02-08 11 views
5

que tienen un número de archivos que se generan en una función definida como:Parece que el archivo se mantiene abierto después de ser enviado como un archivo adjunto por SmtpClient. ¿Cómo puedo eliminar el archivo?

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 

Estos archivos se imprimen inmediatamente y los archivos se guardan automáticamente en un directorio; los archivos en sí mismos no son para el uso real de los usuarios del software. I marca el tiempo de los archivos para mantenerlos identificados de manera única con fines de auditoría.

He recibido el requerimiento de enviar algunos de estos archivos externamente a la empresa, y alguien se ha quejado de que los nombres de archivo actuales no son fáciles de usar.

tanto, he intentado copiar el archivo generado en un directorio temporal, con un nombre más sencillo, enviando un correo electrónico el archivo más amigable, a continuación, eliminarlo, dejando intacta mi pista de auditoría, así:

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 

Esto arroja una System.IO.IOException en la línea System.IO.File.Delete(friendlyFilePath) porque el archivo todavía está en uso, después de haber sido enviado por correo electrónico.

He sacado el código de correo electrónico, lo que hace que la copia y la eliminación funcionen bien, por lo que aparentemente adjunta el archivo al correo electrónico que causa el problema.

También he intentado romper antes de la línea de eliminación, esperando cinco minutos, confirmando que se ha enviado el correo electrónico, y luego avanzando el código, pero todavía se lanza la misma excepción.

¿Alguien puede sugerir cómo resolver este problema?

+0

¿Hay alguna posibilidad de que en esa región [gran cantidad de código] tenga una secuencia de algún tipo que no haya cerrado? –

Respuesta

7

El SmtpClient no suelta el mango de un archivo adjunto. Deberá manejarlo manualmente, o lo que hago es copiar el contenido del archivo a un MemoryStream primero. El siguiente código debería funcionar también.

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

Sí. Eliminó manualmente todos los archivos adjuntos del mensaje de correo electrónico después de su envío. Resuelve el problema. Gracias. – Frosty840

3

Se debe utilizar la instrucción using al acceder a archivos. Esto disponer de su objeto y usted debería ser capaz de llamar a su System.IO.File.Delete()

ver aquí: http://msdn.microsoft.com/en-us/library/htd05whh(v=vs.80).aspx

+0

Este es el mejor resultado ... a menos que usted [por alguna razón] no lo use como 'uso' (luego use la solución de @ Nasir) –

0

cerraste el archivo adjunto después de haberlo creado?

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

Ver this forum donde se ha respondido una pregunta similar. (Está en C# con asp.net, pero debe hacer el truco cuando se convierte en vb.net)

+0

El archivo que se está eliminando se crea usando 'System.IO.File.Copy', entonces su la pregunta no aplica – Frosty840

11

después de añadir mailClient.Send(message);message.Attachments.Dispose();

Esto liberará los recursos de fijación

1

Mientras me di cuenta el último mensaje en este artículo fue hace algunos años que pensé que valía la pena agregar una pequeña cantidad de información adicional para cualquiera que no lo sepa ...

Si está enviando su correo electrónico de forma asincrónica, entonces no puede usar "usar" o deshacerse de nada hasta que la devolución de llamada se active, en su lugar debe enviar su instancia de MailMessage a s el parámetro UserState de SendAsync(). De esta forma, cuando se active la devolución de llamada, podrá deshacerse de los archivos adjuntos y la instancia de MailMessage. También puede deshacerse del cliente de correo ya que será el objeto remitente.

Cuestiones relacionadas