How to send MailMessages using multiple threads?

I hope you guys carry me for my complete lack of direction in the case of Threading. I have to implement a mail queue processing system in which I have to send email queued in the database through the Windows service.

This is not a consumer-manufacturer pattern. I brought 10 lines at a time. The datatable data includes a serialized MailMessage object and SMTP send data. If I need to use a certain number of threads (say 6 threads) Now, how would I like to get a row from the data in the stream, and then send mail and come back again to see if there are more rows left?

Any simple logic to implement this will do, preferably with a simple example in C #.

I am using .NET 3.5

+3
source share
2 answers

Since sending email is an I / O-bound process, therefore spawning streams for sending emails will not bring much success (if any) to speed up.

If you use an SMTP server in this part of Windows, then when you send an email, it is not actually sent at that moment. It is queued on the server, and the server sends them as quickly as possible. Sending email is actually a slow process.

I assume that I say there are two options:

  • Just send them in sequence and see if this meets your performance requirements.
  • " ". " " - #/. NET

, , ( ). , , , ( , ), ( I/O , /, /).

. , . , .

. , . ThreadPool .NET 4.0 ( Parallel.For PLINQ Tasks), , " ", .

Parallel.For/Parallel.ForEach , .

.NET 3.5. , , Parallel.For/ForEach. , ( ), ThreadPool Parallel Data.

    private static void SendEmailsUsingThreadPool(List<Recipient> recipients)
    {
      var coreCount = Environment.ProcessorCount;
      var itemCount = recipients.Count;
      var batchSize = itemCount / coreCount;

      var pending = coreCount;
      using (var mre = new ManualResetEvent(false))
      {
        for (int batchCount = 0; batchCount < coreCount; batchCount++)
        {
          var lower = batchCount * batchSize;
          var upper = (batchCount == coreCount - 1) ? itemCount : lower + batchSize;
          ThreadPool.QueueUserWorkItem(st =>
          {
            for (int i = lower; i < upper; i++)
              SendEmail(recipients[i]);
            if (Interlocked.Decrement(ref pending) == 0)
              mre.Set();
          });
        }
        mre.WaitOne();
      }      
    }

    private static void SendEmail(Recipient recipient)
    {
      //Send your Emails here
    }
  }

  class Recipient
  {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmailAddress { get; set; }
  }

, SendEmailUsingThreadPool(), . , :). DataSet/DataTable, , DataSet/DataTable. , . .

+5

, . ,

0

Source: https://habr.com/ru/post/1794366/


All Articles