2015-06-28 3 views
0

У меня есть следующий код, который показывает отправку электронной почты. Я могу достичь этого через ThreadPool, Task и Async. Вызывающий (в данном случае Основной) не интересуется тем, что возвращается.ThreadPool Vs Task Vs Async

Как я понимаю, все три метода создают дополнительный поток, так что конечный результат тот же.

Пожалуйста, поделитесь, если вы найдете какую-либо другую разницу или что должно быть правильным способом в .NET 4.5?

PS. Если вы хотите скопировать код и запустить его, убедитесь, что вы выбрали объект запуска в настройках проекта. Вы можете выбрать один из основных методов запуска.

using System; 
using System.Threading; 
using System.Threading.Tasks; 

namespace AsyncTest 
{ 
    class ThreadPoolProgram 
    { 
     static void Main(string[] args) 
     { 
      // Dont care what SendEmail returns 
      ThreadPool.QueueUserWorkItem(new WaitCallback(SendEmail)); 
     } 

     static void SendEmail(Object stateInfo) 
     { 
      // Create a SMTP client, send an email and wait for the SMTP client to return! 

      // Takes 2 seconds 
     } 
    } 

    class TaskProgram 
    { 
     static void Main(string[] args) 
     { 
      // Dont care what SendEmail returns 
      Task.Run(() => SendEmail()); 
     } 

     static void SendEmail() 
     { 
      // Create a SMTP client, send an email and wait for the SMTP client to return! 

      // Takes 2 seconds 
     } 
    } 

    class AsyncProgram 
    { 
     static void Main(string[] args) 
     { 
      // Don't await for an answer from the SendMail 
      // var r = await SendEmail(); 

      SendEmail(); // Call without await 
     } 

     static Task<bool> SendEmail() 
     { 
      // Create a SMTP client, send an email and wait for the SMTP client to return! 

      // Takes 2 seconds 

      return Task.FromResult(true); 
     } 
    } 
} 
+0

Плохой пример. Ответ здесь «ни один из вышеперечисленных, использовать SendMailAsync» –

+0

Предполагаю, вы предлагаете использовать SendMailAsync, который входит в состав некоторой библиотеки .NET. Но в этом случае у меня нет библиотеки, но есть некоторый синхронный код в методе SendEmail, который занимает 2 секунды. Вы также можете предположить, что SendEmail происходит из некоторого устаревшего кода, который не возвращает задачу (без async). Мой вопрос касается потока, задачи и асинхронного использования в .NET 4.5. –

+1

_ «Мой вопрос вокруг темы, задачи и асинхронности» _, но также и о Program.Main()? Контекст имеет большое значение. –

ответ

3

кажется резонный вопрос, но контекст делает его трудно дать хороший ответ.

Вы используете консольную программу и Не заботьтесь о том, что возвращает SendEmail. Это не обычный случай.

async/await использует Task s, которые работают поверх ThreadPool. поэтому ваш «против» не задерживается. И, как правило, вы, по крайней мере, заботитесь об ошибках, которые произошли.

Когда вы действительно не заботитесь об ошибках или результатах, QueueUserWorkItem() - это самый простой подход.

В большинстве случаев, однако, вы должны стремиться к ожидаемой задаче. SmtpClient.SendAsync() не является ожидаемым, поэтому задача, которая запускает синхронную Send(), кажется наиболее подходящей.

И когда речь идет о отправке (навалом) писем, у вас будет еще несколько проблем для решения, например, дросселирование количества параллельных вызовов.

+0

Я посмотрел на метод SmtpClient.SendAsync. Если я использую этот метод вместо старого метода синхронизации, который у меня есть, мне не нужно использовать какой-либо из этих методов, потому что «SmtpClient.SendAsync» создает собственный поток. Я прав? –

+1

Надеюсь, он не создаст нить, но будет использовать порты завершения ввода-вывода. И да, для реальной работы Fire & Forget это самый прямой способ. –

+0

Работает ли какая-либо операция ввода-вывода как вызов ReadAsync (https://msdn.microsoft.com/en-us/library/hh137813(v=vs.110).aspx) с использованием WebClient или чтение файла с использованием ReadLineAsync (https: // msdn .microsoft.com/en-us/library/system.io.streamreader.readlineasync (v = vs.110) .aspx) используют порты завершения ввода-вывода и вообще не создают новый поток? –