4

ページが送信プロセスを完了するまでユーザーを待たせたくないので、ASP.NET 3.5 で SendAsync を使用することを考えています。しかし、デバッグ後、メインスレッドがまだ待機していることがわかりました。

Main: メール送信機能を呼び出す...
mailSend: 構成中....
mailSend: 間違ったポートを設定しています....
mailSend: 今すぐ送信を試みます....
mailSend: 行末
Main: メール機能呼び出し終了。
メイン:処理完了!
mailComp: メールの送信に失敗しました。5 秒後に再試行します...
mailComp: 再試行しています...
mailComp: 送信成功!
mailComp: 行末

ここで、間違ったポート設定を配置したため、最初の電子メールが失敗し、2 回目に成功するかどうかをテストします。正しいポートを使用しても、ページは引き続き待機します。mailComp 関数が終了して初めて、ページが最終的に投稿されます。これはSendAsynの制限ですか?

そして、ここにいくつかのコードがありますが、これが役立つかどうかはわかりません.

    protected void btnReset_Click(オブジェクト送信者, EventArgs e)
    {
        試す
        {
            DataContext db = 新しい DataContext();

            var query = db.Fish の u から
                        どこで u.Username == txtUsername.Text & u.Email == txtEmail.Text
                        新しい { u.Username, u.Email } を選択します。

            if (query.Count() != 0)
            {


                ユーザー user = new User();
                文字列トークン = user.requestPasswordReset(txtUsername.Text);
                文字列 URL = Request.Url.AbsoluteUri.ToString() + "?token=" + トークン;
                String body = "パスワードをリセットしています\n" + URL + "\n \n ";


                untilty.SendEmail(txtEmail.Text, "パスワードの再設定", body);

                litTitle.Text = "メッセージが送信されました!";
                litInfo.Text = "詳細については、数分後に記載された電子メールを確認してください。";
                viewMode(偽、偽);
            }
            そうしないと
            {
                litCannotFindUserWithEmail.Visible = true;
            }


        }
        キャッチ(例外例)
        {
            Debug.Write("Main: Exception: " + ex.ToString());
            litInfo.Text = "現在、技術的な問題が発生しています。しばらくしてからもう一度お試しください。問題が解決しない場合は、905344525 までお電話ください";
        }
    }



///
public static class ユーティリティ

///

    public static void SendEmail(文字列の受信者、文字列の件名、文字列の本文)
    {
        MailMessage メッセージ = 新しい MailMessage();

        message.To.Add(新しいメールアドレス(受信者));
        message.From = new MailAddress(fromaddress, "Basadur Profile Web サイト");
        message.Subject = 件名;
        message.Body = 本文;

        メッセージを送る);
    }

    private static void Send(MailMessage msg)
    {
        SmtpClient smtp = new SmtpClient();
        smtp.Host = "smtp.gmail.com";
        smtp.Credentials = new System.Net.NetworkCredential(fromaddress, mailpassword);
        smtp.EnableSsl = true;
        Debug.WriteLine("mailSend: 間違ったポートを設定しています....");
        smtp.Port = 5872; //不正なポート
        smtp.SendCompleted += 新しい SendCompletedEventHandler(smtp_SendCompleted);

        smtp.SendAsync(メッセージ、メッセージ);

    }

    static void smtp_SendCompleted(オブジェクト送信者、System.ComponentModel.AsyncCompletedEventArgs e)
    {
        var msg = (MailMessage)e.UserState;

        if (e.Error != null)
        {
            System.Threading.Thread.Sleep(1000 * 5);

            試す
            {
                SmtpClient smtp = new SmtpClient();
                smtp.Host = "smtp.gmail.com";
                smtp.Credentials = new System.Net.NetworkCredential(fromaddress, mailpassword);
                smtp.EnableSsl = true;
                smtp.Port = 587;
                smtp.Send(メッセージ);
            }
            キャッチ(例外例)
            {
                Debug.WriteLine("mailComp: 2度目の失敗で諦めました。");
            }
        }

    }

4

5 に答える 5

3

.NET 4.5.2 では、リクエストに関係なく、バックグラウンドでタスクをスケジュールするためのメソッドが追加されました: HostingEnvironment.QueueBackgroundWorkItem()

HostingEnvironment.QueueBackgroundWorkItem()System.Web.Hosting名前空間にあります。

ドキュメントのコメントには次のように書かれています。

通常の ThreadPool 作業項目とは異なります。ASP.NET は、この API を通じて登録された作業項目が現在実行されている数を追跡でき、ASP.NET ランタイムは、これらの作業項目の実行が完了するまで AppDomain のシャットダウンを遅らせようとします。

つまり、アプリ ドメインのリサイクル時にタスクが終了しないという確信を持って、ファイア アンド フォーゲット方式でタスクを起動できます。

使用法は次のようになります。

HostingEnvironment.QueueBackgroundWorkItem(cancellationToken =>
{
    try 
    {
       // do work....
    }
    catch(Exception)
    {
        //make sure nothing can throw in here
    }
});
于 2016-02-16T19:47:07.543 に答える
0

以下のコードを使用すると、SmtpClient を使用して asp.net で非同期メールを送信できます。

ThreadPool.QueueUserWorkItem(callback =>
                {
                    var mailMessage = new MailMessage
                    {
                        ...
                    };

                    //if you need any references in handlers
                    object userState = new ReturnObject
                    {
                        MailMessage = mailMessage,
                        SmtpClient = smtpServer
                    };
                    smtpServer.SendCompleted += HandleSmtpResponse;
                    smtpServer.SendAsync(mailMessage, userState);
                });
于 2016-08-04T20:18:25.637 に答える
0

デバッガーは物事をシングルスレッドにするように強制しているようです。ステップスルーすると、各ステップが異なるスレッドを移動するため、2 つの異なるファイル間をジャンプすることになる場合があります。

そこにログを追加して、デバッグなしで実行してみてください。

于 2011-06-29T16:36:04.933 に答える
-3

スレッドを使用する:

// Create the thread object, passing in the method
  // via a ThreadStart delegate. This does not start the thread.
  Thread oThread = new Thread(new ThreadStart(SendMyEmail));

  // Start the thread
  oThread.Start();

これがソースです。完全なスレッド化チュートリアルがあります

于 2011-06-29T15:02:20.497 に答える