How to run multiple operations side by side in .net?

I have an application that takes too long to run, and I want to enter threading / parallelization / whatever.

In particular, the code returns several thousand letters, and then sends them. Today, the code looks like this (a bit simplified):

Dim mails = centreInteretService.GetEmails()
For Each m in mails
    m.Body = GetMailContent(m)
    If MailSendable(m) Then
        SendMail(m)
    End If
Next

I want to try sending several letters in parallel. I would like to try with two threads in parallel. More specifically, I would like to put the whole loop in a stream (getmailcontent + sendmail).

I thought of something like this:

Dim mails1 As New List(Of MailSerialiserCI)
Dim mails2 As New List(Of MailSerialiserCI)
Dim nbFirstList As Integer = CInt(Math.Ceiling(nbTotal / 2))
mails1 = mails.Take(nbFirstList)
mails2 = mails.Skip(nbFirstList)

Dim smt1 As New MailSender.MailSenderThreaded()
smt1.mails = mails1
smt1.nbTotal = nbTotal
Dim threadMails1 As ThreadStart = New ThreadStart(AddressOf smt1.SendMails)
Dim th1 As Thread = New Thread(AddressOf threadMails1)
th1.Start()

Dim smt2 As New MailSender.MailSenderThreaded()
smt2.mails = mails2
smt2.nbTotal = nbTotal
Dim threadMails2 As ThreadStart = New ThreadStart(AddressOf smt2.SendMails)
Dim th2 As Thread = New Thread(AddressOf threadMails2)
th2.Start()

And MailSenderThreaded looks like this:

Public Class MailSenderThreaded
    Public mails As List(Of MailSerialiserCI)
    Public nbTotal As Integer
    Public Sub SendMails()
        LoopMails(Me.mails, Me.nbTotal)
    End Sub
End Class

But strings New Thread(AdressOf x)give me an error: no applicable function x matching delegate System.Threading.ParameterizedThreadStart.

, , , , ; ; .NET 4, .NET 3.5...

, ?

+5
4

, Parallel.ForEach

# :

var mails = centreInteretService.GetEmails();

Parallel.ForEach( mails, new ParallelOptions { MaxDegreeOfParallelism = 2 }, m =>
    {
        m.Body = GetMailContent(m);
        if ( MailSendable(m) ) SendMail(m);
    }
);

EDIT:.NET 3.5!

, .NET 3.5:

(, # - VB. , .)

...
List<Mail> mails = centreInteretService.GetEmails();
var mailer = new Mailer( mails );
mailer.Run();
...

public class Mailer
{
    const int THREAD_COUNT = 2;
    List<Thread> _Threads = new List<Thread>();

    List<Mail> _List = null;
    int _Index = -1;

    public Mailer( List<Mail> list )
    {
        _List = list;
    }

    public void Run()
    {
        for ( int i = 0 ; i < THREAD_COUNT ; i++ )
        {
            _Threads.Add( StartThread() );
        }

        foreach ( var thread in _Threads ) thread.Join();
    }

    Thread StartThread()
    {
        var t = new Thread( ThreadMain );
        t.Start();
        return t;
    }

    void ThreadMain()
    {
        for ( ; ; )
        {
            int index = Interlocked.Increment( ref _Index );
            if ( index >= _List.Count ) return;
            ThreadWork( _List[ index ] );
        }
    }

    void ThreadWork( Mail mail )
    {
        mail.Body = GetMailContent(mail);
        if ( MailSendable(mail) ) SendMail(mail);
    }
}
+4

?

Dim mails = centreInteretService.GetEmails()
For Each m in mails.ASParallel()
    m.Body = GetMailContent(m)
    If MailSendable(m) Then
        SendMail(m)
    End If
Next

1 . 2, :

Dim mails = centreInteretService.GetEmails()
For Each m in mails.AsParallel().WithDegreeOfParallelism(2)
    m.Body = GetMailContent(m)
    If MailSendable(m) Then
        SendMail(m)
    End If
Next

EDIT. .Net 3.5, , Rob Volk . . #, ( 10 ).

+4

, GetMailContent, Send .NET 3.5, Producer-Consumer.

GetMailContent , 1 . , . , , .

Push-based

GetMailContent . , , . Observer.

. / , , .

+1

To use a thread, you must be sure which part of the process should be placed in the stream. As suggested by you, put SendMail(m)in a stream, you have to be sure that this will effectively improve performance. If this is the only part that takes up most of the time, you can put this method into the stream. Or just put the loop in the loop of the loop. See http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx

0
source

All Articles