2009-06-25 6 views
2

Je rencontre des problèmes avec un peu de code que j'écris en C#. J'envoie un document en utilisant les composants MailMessage et SMTP. Je copie les fichiers que je souhaite envoyer vers un répertoire temporaire tel que c: \ temp, boucle les documents et les attache à l'email.La suppression des fichiers échoue en tant que processus existant et en cours

L'email envoie bien, mais quand je tente de supprimer les fichiers du répertoire temporaire, je reçois l'erreur suivante:

The process can not access the file because it is being used by another process

Je ne comprends pas pourquoi cela se passe. Voici le code qui traite les documents

public void sendDocument(String email, string barcode, int requestid) 
    { 

     string tempDir = @"c:\temp"; 

     //first we get the document information from the database. 
     Database db = new Database(dbServer, dbName, dbUser, dbPwd); 

     List<Document> documents = db.getDocumentByID(barcode); 
     int count = 0; 
     foreach (Document doc in documents) 
     { 
      string tempPath = tempDir + "\\" + doc.getBarcode() + ".pdf"; 
      string sourcePath = doc.getMachineName() + "\\" + doc.getFilePath() + "\\" + doc.getFileName(); 

      //we now copy the file from the source location to the new target location 
      try 
      { 
       //this copies the file to the folder 
       File.Copy(sourcePath, tempPath, false); 

      } 
      catch (IOException ioe) 
      { 
       count++; 

       //the file has failed to copy so we add a number to the file to make it unique and try 
       //to copy it again. 
       tempPath = tempDir + "\\" + doc.getBarcode() + "-" + count + ".pdf"; 
       File.Copy(sourcePath, tempPath, false); 

      } 

      //we now need to update the filename in the to match the new location 
      doc.setFileName(doc.getBarcode() + ".pdf");     

     } 

     //we now email the document to the user. 
     this.sendEmail(documents, email, null); 

     updateSentDocuments(documents, email); 

     //now we update the request table/ 
     db.updateRequestTable(requestid); 


     //now we clean up the documents from the temp folder. 
     foreach (Document doc in documents) 
     { 
      string path = @"c:\temp\" + doc.getFileName(); 
      File.Delete(path); 
     } 

    } 

Je pensais que de la méthode this.sendEmail() aurait envoyé de l'e-mail avant de revenir à la méthode sendDocument, car je pense qu'il est l'objet smtp qui est à l'origine les suppressions échouent.

Ceci est la méthode sendEmail:

public void sendEmail(List<Document> documents, String email, string division) 
    { 
     String SMTPServer = null; 
     String SMTPUser = null; 
     String SMTPPwd = null; 
     String sender = ""; 
     String emailMessage = ""; 

     //first we get all the app setting used to send the email to the users 
     Database db = new Database(dbServer, dbName, dbUser, dbPwd); 

     SMTPServer = db.getAppSetting("smtp_server"); 
     SMTPUser = db.getAppSetting("smtp_user"); 
     SMTPPwd = db.getAppSetting("smtp_password"); 
     sender = db.getAppSetting("sender"); 
     emailMessage = db.getAppSetting("bulkmail_message"); 

     DateTime date = DateTime.Now; 

     MailMessage emailMsg = new MailMessage(); 

     emailMsg.To.Add(email); 

     if (division == null) 
     { 
      emailMsg.Subject = "Document(s) Request - " + date.ToString("dd-MM-yyyy"); 
     } 
     else 
     { 
      emailMsg.Subject = division + " Document Request - " + date.ToString("dd-MM-yyyy"); 
     } 

     emailMsg.From = new MailAddress(sender); 
     emailMsg.Body = emailMessage; 

     bool hasAttachements = false; 

     foreach (Document doc in documents) 
     { 

      String filepath = @"c:\temp\" + doc.getFileName(); 

      Attachment data = new Attachment(filepath); 
      emailMsg.Attachments.Add(data); 

      hasAttachements = true; 


     } 

     SmtpClient smtp = new SmtpClient(SMTPServer); 

     //we try and send the email and throw an exception if it all goes tits. 
     try 
     { 
      if (hasAttachements) 
      { 
       smtp.Send(emailMsg); 
      } 
     } 
     catch (Exception ex) 
     { 
      throw new Exception("EmailFailure"); 
     } 


    } 

Comment je contourner ce problème avec un processus monopolisant le fichier que je souhaite supprimer.

Je peux supprimer le (s) fichier (s) une fois l'application terminée.

Répondre

6

vous êtes message n'est pas Disposé, essayez la disposition après que vous avez envoyé:

try 
{ 
     if (hasAttachements) 
     { 
      smtp.Send(emailMsg);   
     } 
} 
catch ... 
finally 
{ 
     emailMsg.Dispose(); 
} 
1

La première étape consiste à déterminer quel processus tient sur le fichier en question. Je voudrais saisir le toolkit SysInternals et utiliser la commande handle.exe pour déterminer quel processus tient sur le fichier.

Sans savoir quel processus le fichier est ouvert, il n'existe aucun moyen de résoudre ce problème.

Sysinternals Lien: http://technet.microsoft.com/en-us/sysinternals/default.aspx

+0

merci pour le lien vers ces outils ... très utiles ... –

0

Voici un truc que je viens discoverred, qui nous l'espérons, être utile à d'autres gens? Avant d'ajouter des pièces jointes à un message, créez la pièce jointe dans un encapsuleur. Cela garantit qu'il est correctement éliminé, ce qui permet de supprimer le fichier avec succès. Je ne suis pas sûr si l'envoi doit également être dans cette boucle; (Quand j'ai testé, les emails ne sont pas arrivés au début, puis une demi-heure plus tard j'ai été inondé, donc j'ai décidé de laisser les tests à un moment où le réseau était un peu plus calme).

using (Attachment attachment = new Attachment(filename)) 
{ 
    message.Attachments.Add(attachment); 
    client.SendAsync(message, string.Empty); 
} 
File.Delete(filename); 

OK pour moi Works de toute façon :)

Bonne chance,

JB

Questions connexes