如何在.net中并行启动多个操作?

tho*_*asb 5 .net multithreading .net-3.5

我有一个运行时间太长的应用程序,我想引入线程/并行化/无论如何.

具体来说,代码会检索几千封邮件,然后发送它们.今天,代码看起来像这样(有点简化):

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

我想尝试并行发送多封邮件.我想尝试并行使用2个线程.更具体地说,我想将整个循环放在一个线程中(getmailcontent + sendmail).

我想到了这样的事情:

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()
Run Code Online (Sandbox Code Playgroud)

MailSenderThreaded是这样的:

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
Run Code Online (Sandbox Code Playgroud)

但这些线条New Thread(AdressOf x)给我一个错误:no applicable function x matching delegate System.Threading.ParameterizedThreadStart.

我试着在这里和那里搜索,但我只能找到需要比我更多知识的解决方案; 或线程基础; 或.NET 4的东西,但我们仍然在.NET 3.5 ...

你有一个我可以尝试的简单解决方案吗?

谢谢

Nic*_*ler 4

如果循环体是线程安全的,则可以使用Parallel.ForEach

在 C# 中,它看起来像这样:

var mails = centreInteretService.GetEmails();

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

编辑:.NET 3.5!

我认为这是 .NET 3.5 中最简单的解决方案:

(抱歉,这是用 C# 编写的 - 我不懂 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);
    }
}
Run Code Online (Sandbox Code Playgroud)