ASP.NET 2.0中的SmtpClient.SendAsync错误

时间:2020-03-05 18:58:08  来源:igfitidea点击:

我可能是错的,但是如果我们正在使用ASP.NET中的SmtpClient.SendAsync,
2.0并引发异常,处理请求的线程等待
无限期地完成手术。

要重现此问题,只需为主机使用无效的SMTP地址
发送电子邮件时无法解决的问题。

请注意,我们应该将Page.Async = true设置为使用SendAsync。

如果Page.Async设置为false并且Send引发异常,则线程
不会阻止,并且页面已正确处理。

TIA。

解决方案

回答

Note that you should set Page.Async = true to use SendAsync.

请解释其背后的理由。误解Page.Async所做的事情可能是导致我们出现问题的原因。

抱歉,我无法获得可以重现该问题的示例。

请参阅http://msdn.microsoft.com/zh-cn/magazine/cc163725.aspx(邪恶代码:ASP.NET 2.0中的异步页面)

编辑:查看代码示例,我可以看到我们没有使用RegisterAsyncTask()PageAsyncTask类。我认为在将@Async设置为true的页面上执行异步任务时,必须执行此操作。来自《 MSDN杂志》的示例如下所示:

protected void Page_Load(object sender, EventArgs e)
{
    PageAsyncTask task = new PageAsyncTask(
        new BeginEventHandler(BeginAsyncOperation),
        new EndEventHandler(EndAsyncOperation),
        new EndEventHandler(TimeoutAsyncOperation),
        null
        );
    RegisterAsyncTask(task);
}

那么,在" BeginAsyncOperation"内部,我们应该异步发送邮件吗?

回答

这是我的。试试看。

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Using an incorrect SMTP server
        SmtpClient client = new SmtpClient(@"smtp.nowhere.private");
        // Specify the e-mail sender.
        // Create a mailing address that includes a UTF8 character
        // in the display name.
        MailAddress from = new MailAddress("[email protected]",
           "SOMEONE" + (char)0xD8 + " SOMEWHERE",
        System.Text.Encoding.UTF8);
        // Set destinations for the e-mail message.
        MailAddress to = new MailAddress("[email protected]");
        // Specify the message content.
        MailMessage message = new MailMessage(from, to);
        message.Body = "This is a test e-mail message sent by an application. ";
        // Include some non-ASCII characters in body and subject.
        string someArrows = new string(new char[] { '\u2190', '\u2191', '\u2192', '\u2193' });
        message.Body += Environment.NewLine + someArrows;
        message.BodyEncoding = System.Text.Encoding.UTF8;
        message.Subject = "test message 1" + someArrows;
        message.SubjectEncoding = System.Text.Encoding.UTF8;
        // Set the method that is called back when the send operation ends.
        client.SendCompleted += new
        SendCompletedEventHandler(SendCompletedCallback);
        // The userState can be any object that allows your callback 
        // method to identify this send operation.
        // For this example, the userToken is a string constant.
        string userState = "test message1";
        try
        {
            client.SendAsync(message, userState);
        }
        catch (System.Net.Mail.SmtpException ex)
        {
            Response.Write(string.Format("Send Error [{0}].", ex.InnerException.Message));
        }
        finally
        {
        }
    }
    private void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
    {
        // Get the unique identifier for this asynchronous operation.
        String token = (string)e.UserState;

        if (e.Cancelled)
        {
            Response.Write(string.Format("[{0}] Send canceled.", token));
        }
        if (e.Error != null)
        {
            Response.Write(string.Format("[{0}] {1}", token, e.Error.ToString()));
        }
        else
        {
            Response.Write("Message sent.");
        }
    }

}

回答

无法使用RegisterAsyncTask。
查看BeginEventHandler委托:

公共委托IAsyncResult BeginEventHandler(
对象发送者,
EventArgs e,
AsyncCallback cb,
对象extraData
)

它应该返回一个IAsyncResult。
现在看一下SmtpClient.SendAsync函数:

公共无效SendAsync(
MailMessage消息,
对象userToken
)

没有返回值。

无论如何,只要SmtpClient.SendAsync不引发异常,它就可以正常工作。