2017-06-11 27 views
2

私はMailKit/MimeKitで遊んでいて、何かが私を悩ませています。ストリームを使って添付ファイル付きの電子メールを送ろうと思っていました。 MimeKitは、身体のメッセージを作成し、ファイルを添付することが非常に容易になりますBodyBuilderクラスを提供しています:添付ファイル付きの電子メールを送信するときにMimeKitで使用されるストリームを破棄する必要がありますか?

public void SendEmail(string body, Stream attachment, string fileName) 
{ 
    var message = new MimeMessage(); 
    message.From.Add(new MailboxAddress("Carl", "[email protected]")); 
    message.To.Add(new MailboxAddress("Rick", "[email protected]")); 
    message.Subject = "Things got messy...?"; 

    var builder = new BodyBuilder(); 
    builder.TextBody = body; 

    builder.Attachments.Add(fileName, attachment); 

    message.Body = builder.ToMessageBody(); 

    using (var client = new SmtpClient()) 
    { 
     // code to send e-mail here... 
    } 
} 

私は他の場所で私のコードでストリームを生成し、私はそれを閉じていないので、私はMimeKitへのそれを渡すことができます。明確ではないことは、MimeKitはストリームを破棄しますか?基本的には(私が知っている限り)消費者は通常Streamsを廃棄する責任があります。また、私は基本的に使用しているMemoryStreamでdisposeを呼び出すと、リソースを解放することはできませんが、読み書きはできません。しかし、将来、実装が別のタイプのストリームに変更されると、事態がより複雑になる可能性があります。

私もMikeKitのソースコードに掘る、とAttachmentCollection.Addに渡されたストリームは、ストリームから継承(および廃棄を実装)MemoryBlockStreamに「追加」されますので、私はこの時、それはの配置されたを取得想定したがいことがわかりましたポイント、私はちょうど推測しています。

アイデア?

答えて

1

MimeKitのコードを検査します。特に、2つのオーバーロード:

1 - Overloadには、byte[] dataが必要です。これらのオーバーロードはストリームを作成し、その所有権を保持していることがわかります。これはストリームをusing blockに作成することで完了です。ストリーム下流のコード(CreateAttachment())がストリーム処理を処理していないと仮定できます。

2 - overload that you mentionの場合、ストリームはただちにCreateAttachment()に渡されます。

私は、この場合、可能ならば自分で処分する方が良いと言いたいと思います。つまり、ストリームが1回だけ消費された場合のみ実行できます。

実際には、Addを呼び出した後、ストリームが既に消費されていました。メソッドが返ったら、すべてのデータがメモリに格納され、ストリームを破棄できます。 LoadContent()でこれを見ることができます。

MemoryStreamを持っていて、Disposeを必要とする別のストリームが後で使用できるため、Disposeの呼び出しを避けたいのと同じように。 Addを呼び出した後にストリームを廃棄することは悪い考えです。 ライブラリーの動作が将来変更され、Addへの呼び出し時にストリームがまだ消費されていない場合(これは私の考えでは予想される動作です)。

ストリームは、NetworkSocketにデータを書き込むときにのみ読み込みされます。実際には、データをすべてRAMにロードせずにストリーミングします。

この場合、Mailkit.Sendが呼び出された後にのみストリームを廃棄することができます。

1

これらのストリームを破棄する必要はありません。あなたが望むことができますが、それは必要ではありません。

+0

これがなぜ「なぜ」になるのでしょうか? 'MimeKit'はあなたのためにこれをしていますか?この質問は、私たち(よく、ヒープと私たちのdevsのヒープ)が ''身代金 'を継承するので、そのクラスの処理を断念する' 'HttpClient'シナリオに戻って考えますが、2016年にはそれをシングルトンではなくdispose(なぜコードサンプルで説明されたのか)。だから - ちょうど学びたい: –

+1

それはまさに私のポイントだった。私は答えを知っていたので、まず質問が必要ないと主張することができました。しかし、私はそれがどのように機能するのか知りたかったので、私は盲目的にやっていません。 – jpgrassi

+0

MemoryBlockStreamのDisposeメソッドは、バイト配列を破棄することができないため、操作しません。 Disposeメソッドは、クラスがアンマネージリソースを使用する場合にのみ必要です。 – jstedfast

関連する問題