メールライブラリのバグ対応  2020年6月3日記

0.初めに

初めに

 .NET プログラムから利用できるメール用ライブラリとして、 Microsoft 社では自社のライブラリではなく MailKit と呼ばれているライブラリの使用を推奨しています。
 そのライブラリを以下のような手順で使用した時に問題に遭遇しました。

  • 複数の取引先の情報を格納した PDF ファイルがあります
  • 上記 PDF ファイルを取引先ごとに分割した PDF ファイルを新規に作成します
  • 分割した PDF ファイルを添付して、取引先にメールを送信します
  • メール送信後、一時的に作成した PDF ファイルを削除します
    このとき、PDF ファイルの削除に失敗してしまいました

 メールに添付したファイルを、メール送信後に直ちに削除するといった運用は珍しいかもしれません。この時は、添付ファイルは一時的に作成したものであるため、保存しておく必要がなかったのです。
 さてこの問題をどのように解決したでしょうか

1.解決方法

原因の予想

 添付ファイルの削除に失敗することから、メールライブラリが添付ファイルのファイルハンドルをつかんだままになっているのではないかと予想しました。とすれば、メール送信後にその添付ファイルのファイルハンドルを明示的に開放してあげればよいのではないか?と考えました。

解決方法

 そこで、次のようなソースに変更したところ、添付ファイルの削除を行うことができました。  いづれもプログラム片ですが、添付ファイルを指定する部分を以下のようにします。

					
// 添付ファイルを指定する部分

1    Multipart multipart = null;
2    List<MimePart> mimes = new List<MimePart>();
3    multipart = new Multipart("mixed");
4    multipart.Add(textPart);

5    MimePart mime;
6    foreach (var name in files)
7    {
8        mime = getMimePart(name);
9        mimes.Add(mime);

10       multipart.Add(mime);
11   }		
					
					
1行目 MailKit の Multipart オブジェクト用変数
2行目 今回のバグに対応した部分.メール送信後のために保存しておきます
5行目 MailKit の MimePart オブジェクト用変数
6~11行目 添付ファイルの数だけ繰り返し処理をします
8行目 ファイル名の拡張子から MimePart オブジェクトを決めるためのアプリケーション専用の関数です
9行目 メール送信後に、ファイルハンドルを開放するために一時的に保存しておきます

					
// メール送信後に添付ファイルのハンドルを開放する部分

1    foreach (var m in mimes)
2    {
3        m.Content.Stream.Dispose();
4    }
					
					
1~4行目 添付ファイルの数だけ繰り返し処理をします
3行目 ファイルハンドルを明示的に開放します