- PR -

【ASP.NET】非同期によるメール送信について

1
投稿者投稿内容
アキミ
常連さん
会議室デビュー日: 2003/05/30
投稿数: 21
投稿日時: 2004-03-12 15:45
お世話になっております。

ASP.NETからメールを送信するクラスを作成し、それ自体はうまく
動いているのですが、これを非同期によるメール送信にしようと
したら、詰まってしまいました…。

コード:

'アラートメールのクラス定義
Dim myAlertMail As New AlertMail
'社員へのメール送信クラスをデグレードする
Dim alertMailDeleg As New SendMailDelegate(AddressOf myAlertMail.SendMail)
'アラートメールの送信をスレッドで定義
alertMailDeleg.BeginInvoke(Me.Year, Me.KashoCD, Me.SeiriNo, Nothing, Nothing)



という感じで、ある帳票のデータをメールで送信します。
メールの処理はクリティカルではなく、あくまで登録したら
知らせるという感じの機能です。

そのため
・途中で何らかしらのエラーが発生しても処理を続ける
・リアルタイム送信ではないので、登録処理を優先
という条件があります。

そのために非同期によるメール送信を実装しようとして
いたのですが…。

上記のコードを見て頂くと解ると思うのですが、呼出し
元のインスタンスが終了すると、メールの送信が行われ
ないまま、終了します。
よく考えてみれば、当然なのですが…。

完全に別プロセスで動かさないと行けないことなのでし
ょうか?調べてはいるのですが、つまってしまいました。

極力、自分で勉強していきたいと思うのですが、なにか
ヒントのようなモノがありましたら、教えていただけま
すでしょうか?よろしくお願い致します。

[ メッセージ編集済み 編集者: アキミ 編集日時 2004-03-12 15:46 ]
masas
常連さん
会議室デビュー日: 2002/05/23
投稿数: 25
投稿日時: 2004-03-12 16:00
私もよくわからないのですが、スレッドのJoinをしてみたらいかがでしょう?!
メインスレッドが終わる前に、メールスレッドに対しThread.Join();をコールすると。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2004-03-12 16:12
引用:

アキミさんの書き込み (2004-03-12 15:45) より:
コード:
'アラートメールのクラス定義
Dim myAlertMail As New AlertMail
'社員へのメール送信クラスをデグレードする
Dim alertMailDeleg As New SendMailDelegate(AddressOf myAlertMail.SendMail)
'アラートメールの送信をスレッドで定義
alertMailDeleg.BeginInvoke(Me.Year, Me.KashoCD, Me.SeiriNo, Nothing, Nothing)




用語はなるべく正確に記述した方が良いですよ。違う意味になっちゃってます…

引用:

上記のコードを見て頂くと解ると思うのですが、呼出し
元のインスタンスが終了すると、メールの送信が行われ
ないまま、終了します。
よく考えてみれば、当然なのですが…。


うーん、そういうわけではないと思いますが、まあ、EndInvoke実行しないことになるからまずいというのはあるでしょうけど。
そういう意味ではコールバックを登録しておけば済む気もしますが。
「元のインスタンスが終了する」の意味が良く分かりませんが、メソッドを抜けると非同期実行が勝手にキャンセルされる、というようなことはありません、基本的に。
# というか、非同期実行はそういう状況でよく使いますよね。

> ・途中で何らかしらのエラーが発生しても処理を続ける
> ・リアルタイム送信ではないので、登録処理を優先
この目的で、本当に非同期実行を使うのが望ましいかというのもあります。
単純に処理を先に実行して、処理が完了したらメールを同期送信でもいいような気がします。メール送信でのエラー処理(ログをはくのか単に無視するのかは知りませんが)はする必要があるでしょうけど。
メール送信に時間がかかったり、タイムアウトするような場合に待つのがいやなら非同期でやる必要があるかも知れませんが。

あるいは、メッセージキューなんてのもあるかも(そこまでいらんでしょうけど)。
アキミ
常連さん
会議室デビュー日: 2003/05/30
投稿数: 21
投稿日時: 2004-03-12 16:32
>>masasさん

ありがとうございます。

この場合、alertMailDelgにはjoinメソッドが存在しませんでした。
もうちょっと、調べてみようと思います。
わからないことだらけで、申し訳ありません。

>>なちゃさん

ありがとうございます。

引用:

用語はなるべく正確に記述した方が良いですよ。違う意味になっちゃってます…


コメントについては、私自身ものすごく自身がなかったのですが、
勉強しなおします…。すいません。

ASP.NETではPage_Loadから始まって、その中の処理をすべて完了したら
そのインスタンスはメモリから解放されてしまうのかと思っていたので、
内部で呼ばれた非同期処理もキャンセルされてしまうと思ってしまいま
した…。

非同期処理を使ってみたかったというのは、メール送信に時間がかかっ
てしまい、クライアントの表示が遅くなってしまうかも…と考えた為で
す。登録をするユーザにはメールを送信しているという意識はないので
その為に遅くならないようにしよう。という考えがありました。

ただ、実際にメール送信の機能を実装してみたらレスポンスは殆どかわ
らなかったので、非同期処理にする必要もなく、半分は勉強になってい
ます。


[ メッセージ編集済み 編集者: アキミ 編集日時 2004-03-12 16:34 ]
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2004-03-12 16:32
引用:

masasさんの書き込み (2004-03-12 16:00) より:
私もよくわからないのですが、スレッドのJoinをしてみたらいかがでしょう?!
メインスレッドが終わる前に、メールスレッドに対しThread.Join();をコールすると。


そ、それはちょっとむちゃ…
あ、いや、もしかして非同期実行を使うんではなく、自分で明示的にスレッドを作ってって事でしょうか?

「最終的に待つ」だけであれば、最初に非同期実行しておいて、最後に抜ける前にEndInvokeしたらいいと思いますが。ただ、そのほう方がいいかどうかは別問題です。例えば本来の処理が成功したかどうか分かる前にメール送信を開始していいのかとか、最終的にEndInvokeするのは結局最後の部分で同期になるので、元々の目的を満たせていないかも、とか。

まあ、多分masasさんが書かれたのは、アキミさんのメソッドが終了してしまって実行されないという部分に関してだとは思いますが。
masas
常連さん
会議室デビュー日: 2002/05/23
投稿数: 25
投稿日時: 2004-03-12 16:37
引用:

まあ、多分masasさんが書かれたのは、アキミさんのメソッドが終了してしまって実行されないという部分に関してだとは思いますが。


そういう意味で捉えました。
私も過去に同様なことをやりたいと思いまして、結局どうしたかというと、メール送信用のテーブルを作成し、処理が完了した時点でそこにINSERTする。実際のメール送信は、C#でサービスとして作りました。これが一番確実でスマートでした。
1

スキルアップ/キャリアアップ(JOB@IT)