2009-12-04 5 views
4

Je suis en train de mettre en place un service d'abonnement pour envoyer des rapports à diverses personnes dans notre entreprise sur un calendrier. Je prévois d'envoyer les rapports par courrier électronique, le système de rapport que j'utilise est capable d'exporter en flux PDF (plutôt que d'écrire des fichiers temporaires). La plupart des gens recevront plus d'un rapport, donc je suis en train de les attacher à un e-mail faire quelque chose commeC# List <Stream> disposer/fermer

List<Stream> reports = new List<Stream>(); 
//looping code for each users set of reports 
Stream stream = ReportSource.ReportDocument.ExportToStream(PortableDocFormat) 
reports.Add(stream); 
stream.Flush(); //unsure 
stream.Close(); //unsure 
//end looping code 

SmtpClient smtpClient = new SmtpClient(host, port); 
MailMessage message = new MailMessage(from, to, subject, body); 

foreach (Stream report in reports) 
{ 
    message.Attachments.Add(new Attachment(report, "application/pdf")); 
}     
smtpClient.Send(message); 

Ce que je ne suis pas sûr au sujet est devrais-je vider et fermer le flux juste après l'avoir ajouté à la liste Est-ce que ça va aller? Ou ai-je besoin de boucler la liste pour la rincer et la jeter? J'essaie d'éviter toute fuite de mémoire possible.

Répondre

18

Pourquoi ne pas créer une classe StreamCollection qui implémente IDisposable:

public class StreamCollection : Collection<Stream>, IDisposable { } 

Dans la méthode Dispose de cette classe, vous pourriez créer une boucle à travers tous les cours d'eau et à fermer correctement/Eliminer chaque flux. Alors votre code ressemblerait à:

using (var reports = new StreamCollection()) 
{ 
    //looping code for each users set of reports 
    reports.Add(ReportSource.ReportDocument.ExportToStream(PortableDocFormat)); 
    //end looping codeSmtpClient 

    smtpClient = new SmtpClient(host, port); 
    MailMessage message = new MailMessage(from, to, subject, body); 

    foreach (Stream report in reports) 
    {  
     message.Attachments.Add(new Attachment(report, "application/pdf")); 
    } 

    smtpClient.Send(message); 
} 
+0

pwetty! +1 15chars – Quibblesome

+1

Vous pourriez rendre StreamCollection générique, alors il peut être utilisé pour n'importe quel objet IDisposable – thecoop

+0

Comme cette approche l'utilisera – PeteT

0

Il n'y a aucun mal à faire Flush()/Close(). Si vous voulez être absolument sûr, alors vous devriez faire une déclaration utilisant:

using (Stream stream = ReportSource.ReportDocument.ExportToStream(PortableDocFormat)) 
{ 
    reports.Add(stream); 
    stream.Flush(); //unsure 
} 

De cette façon, les exceptions n'affectera pas votre code.

1

Dépend si les flux sont utilisés plus tard lors de la création de la pièce jointe. Je suppose qu'ils sont ce qui signifie que vous aurez envie de disposer des flux à la fin.

N'oubliez pas d'essayer-enfin cela. Sinon, ils ne seront pas éliminés si une exception se produit.

+0

je partais juste le code simple pour l'exemple, savez faire essayer finallys et tout cela. – PeteT

1

Je ne vois pas la logique dans la fermeture des flux juste après l'ajout à la liste. Basé sur le code que vous avez fourni, il apparaît que les références à ces flux sont utilisées dans d'autres endroits. Si les cours d'eau sont fermés, à quoi servent-ils?

3

Vous pouvez créer un DisposableList que vous pouvez envelopper dans une déclaration à l'aide:

public class DisposableList<T> : List<T>, IDisposable where T : IDisposable { 

    // any constructors you need... 

    public void Dispose() { 
     foreach (T obj in this) { 
      obj.Dispose(); 
     } 
    } 
} 
Questions connexes