Ошибка SmtpClient.SendAsync в ASP.NET 2.0

Я могу ошибаться, но если вы работаете с SmtpClient.SendAsync в ASP.NET 2.0 и он выдает исключение, поток, обрабатывающий запрос, бесконечно ждет завершения операции.

Чтобы воспроизвести эту проблему, просто используйте неверный SMTP-адрес для хоста, который не может быть разрешен при отправке электронной почты.

Обратите внимание, что вы должны установить Page.Async = true, чтобы использовать SendAsync.

Если для Page.Async установлено значение false, а Send выдает исключение, поток не блокируется и страница обрабатывается правильно.

ТИА.


person Olivier MATROT    schedule 17.09.2008    source источник


Ответы (3)


<удар>

Обратите внимание, что вы должны установить Page.Async = true, чтобы использовать SendAsync.

Пожалуйста, объясните причину этого. Причиной ваших проблем может быть непонимание того, что делает Page.Async.

Извините, мне не удалось запустить пример, воспроизводящий проблему.

См. http://msdn.microsoft.com/en-us/magazine/cc163725.aspx (ПЛОХОЙ КОД: асинхронные страницы в ASP.NET 2.0)

EDIT: Глядя на ваш пример кода, я вижу, что вы не используете RegisterAsyncTask() и класс PageAsyncTask. Я думаю, вы должны сделать это при выполнении асинхронных задач на странице, где для @Async установлено значение true. Пример из MSDN Magazine выглядит так:

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 вы должны отправлять почту асинхронно.

person bzlm    schedule 17.09.2008

Не удалось использовать RegisterAsyncTask. Посмотрите на делегата BeginEventHandler:

открытый делегат IAsyncResult BeginEventHandler (отправитель объекта, EventArgs e, AsyncCallback cb, дополнительные данные объекта)

Он должен вернуть IAsyncResult. Теперь посмотрим на функцию SmtpClient.SendAsync:

public void SendAsync (сообщение MailMessage, объект userToken)

Нет возвращаемого значения.

В любом случае это работает нормально, пока SmtpClient.SendAsync не выдает исключение.

person Olivier MATROT    schedule 14.10.2008

Вот мой. Попробуйте.

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.");
        }
    }

}
person Olivier MATROT    schedule 17.09.2008