Как вызвать метод асинхронно

Я пытался перейти по этой ссылкеАсинхронный вызов но некоторые классы устарели.
Поэтому я хочу точный ответ для моего проекта.

<code>public class RegisterInfo
{
    public bool Register(UserInfo info)
    {
        try
        {
            using (mydatabase db = new mydatabase())
            {
                userinfotable uinfo = new userinfotable();
                uinfo.Name = info.Name;
                uinfo.Age = info.Age;
                uinfo.Address = info.Address;

                db.userinfotables.AddObject(uinfo);
                db.SaveChanges();

                // Should be called asynchronously
                Utility.SendEmail(info); // this tooks 5 to 10 seconds or more.

                return true;
            }
        }
        catch { return false; }
    }
} 

public class UserInfo
{
    public UserInfo() { }

    public string Name { get; set; }
    public int Age { get; set; }
    public string Address { get; set; }
}  

public class Utility
{
    public static bool SendEmail(UserInfo info)
    {
        MailMessage compose = SomeClassThatComposeMessage(info);
        return SendEmail(compose);
    }

    private static bool SendEmail(MailMessage mail)
    {
        try
        {
            SmtpClient client = new SmtpClient();
            client.Host = "smtp.something.com";
            client.Port = 123;
            client.Credentials = new System.Net.NetworkCredential("[email protected]", "password");
            client.EnableSsl = true;

            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
            client.Send(mail);

            return true;
        }
        catch { return false; }
    }
}    
</code>

Пожалуйста, посмотрите наRegister метод. После сохранения данных я не хочу ждать отправки почты. Если возможно, я хочу обработать отправку почты в другом потоке, чтобы пользователь не стал дольше ждать.
Мне не нужно знать, была ли почта успешно отправлена.
Надеюсь, вы поняли, о чем я. Извините за мой плохой английский.

 cubski12 апр. 2012 г., 06:34
В вашем коде есть ошибка, когда функция SendEmail выдает исключение, она возвращает false, но в функции Register она по-прежнему возвращает true. Это предполагает, что bool означает успех / неудачу.
 nawfal10 июн. 2014 г., 12:14
возможный дубликатHow to call any method asynchronously in c#
 fiberOptics12 апр. 2012 г., 09:59
Спасибо за беспокойство, но это не оригинальный код. Я просто хотел знать, как сделать асинхронный вызов.

Ответы на вопрос(4)

SendAsync метод. Для этого вам не нужно писать собственный асинхронный код.

@ Комментарий о том, что SmtpClient не работает "из коробки" с ASP.NET:
Это абсолютно не так, это прекрасно работает и является рекомендуемым API. Однако вы должны пониматьASP.NET Page Life-Cyclи как многопоточность ведет себя на сервере. В противном случае нет причин не использовать его.

 12 апр. 2012 г., 05:54
По вашей ссылке я увидел, что он не будет работать нормально из коробки с ASP.NET. Просто хочу выделить этоblog.jdconley.com/2009/01/…
 12 апр. 2012 г., 06:49
Вы должны настроить свою страницу так, чтобы она учитывала асинхронные методы и следила за тем, чтобы вы правильно следовали жизненному циклу страниц. В противном случае нет ничего плохого в использовании SendAsync. В блоге обсуждается проблема с загрузкой, которая не является проблемой с хорошим дизайном и надлежащим оборудованием для ожидаемой загрузки ваших страниц.
 fiberOptics12 апр. 2012 г., 06:09
Thread и ThreadPool работают, так в чем же разница? Что лучше всего использовать?
 12 апр. 2012 г., 06:11
Для очень короткой задачи, подобной этой, ThreadPool больше подходит. Это накладные расходы на запуск & amp; завершающие потоки, так что более эффективно использовать существующий поток, а не запускать собственный.

Или используяАсинхронная ОСАГО.

public async Task<bool> Register(UserInfo info)
{
    try
    {
        using (mydatabase db = new mydatabase())
        {
            userinfotable uinfo = new userinfotable();
            uinfo.Name = info.Name;
            uinfo.Age = info.Age;
            uinfo.Address = info.Address;

            db.userinfotables.AddObject(uinfo);
            db.SaveChanges();

            //Wait for task to finish asynchronously
            await Utility.SendEmail(info);

            return true;
        }
    }
    catch { return false; }
}

private Task SendEmail(MailMessage mail)
{
    SmtpC,lient client = new SmtpClient();
    client.Host = "smtp.something.com";
    client.Port = 123;
    client.Credentials = new System.Net.NetworkCredential("[email protected]", "password");
    client.EnableSsl = true;

    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);

    //The smtp SendTaskAsync is an extension method when using Async CTP
    return client.SendTaskAsync("from", "recipients", "subject", "body");
}

Существует также ошибка в вашем исходном коде. Когда исключение выдается внутри функции SendEmail, оно возвращает false, но внутри функции регистра оно все равно возвращает true. Предполагая, что bool означает успех или неудачу.

Решение Вопроса

С помощьюThread:

new Thread(() => Utility.SendEmail(info)).Start();

С помощьюThreadPool:

ThreadPool.QueueUserWorkItem(s => Utility.SendEmail(info));

С помощьюTask:

Task.Factory.StartNew(() => Utility.SendEmail(info));

Of course Thread and ThreadPool require using System.Threading while Task requires using System.Threading.Tasks

Как указаноДэвид Андерсон, SmtpClient уже поддерживаетасинхронная отправка (I probably should have paid attention to the content of the function rather than answering the question)так что технически вы могли бы просто использовать это для обработки отправки, хотя это не разгрузит обработку всего вашего метода.

 fiberOptics12 апр. 2012 г., 05:57
Речь меньше. Так здорово, спасибо !!!
 12 апр. 2012 г., 06:55
@DavidAnderson - Ценится. Я фактически использовал его в прошлом в MVC с большим успехом, поэтому я удивлен, узнав, что это не рекомендуется.
 12 апр. 2012 г., 05:48
Впервые я увидел это с лямбда-выражением. Потребовалось несколько секунд, чтобы понять, как это работает. +1
 12 апр. 2012 г., 05:49
Лямбда-наркоман - & gt;
 12 апр. 2012 г., 07:01
Эрг, вы должны заметить, что это был очень долгий день. В использовании System.Net.Mail.SmtpClient нет ничего плохого. System.Web.Mail.SmtpMail устарел, и вы должны использовать * .Net.Mail.SmtpClient. (Читайте мой обновленный пост)

Ваш ответ на вопрос