多线程的foreach

时间:2013-10-16 06:33:39

标签: c# multithreading .net-3.0

我在数据集中有ReferenceIDs(字符串)列表。这些ReferenceID可以有这样的值(“CQ1258891”,“CQ1258892”,“CQ1258893”......“”CQ1258993“。我的代码中有一个逻辑,可以为每个ReferenceID发送邮件。

截至目前,我正在循环遍历每个ReferenceID。因此,发送每封邮件需要更多时间。 我一直在使用.NET 3.0,所以我没有选择在.NET 4.0中使用TPL。

我一直在寻找一种多线程机制来异步发送每个ReferenceID的邮件。截至目前,我已经尝试了以下代码,但它没有按预期工作。

foreach (DataRow row in qrefSet.Tables[0].Rows)
{
    string refId = Convert.ToString(row["ReferenceID"]);
    if (!string.IsNullOrEmpty(refId))
    {
        Thread thread = new Thread(() => apeDBAdapter.SendEmail(personId, refId, parentReferenceID, customerName, queueId));                                    
        thread.Start();
    }
}

请分享有效的机制来实现我的实现的多线程foreach循环。

谢谢, 斯利拉姆

3 个答案:

答案 0 :(得分:2)

试试这个

foreach (DataRow row in qrefSet.Tables[0].Rows)
{
    string refId = Convert.ToString(row["ReferenceID"]);
    if (!string.IsNullOrEmpty(refId))
    {
        Thread thread = new Thread(new ParameterizedThreadStart(SendMail));
        thread.Start(refId)           
    }
}
..........
void SendMail(object refId)
{
    string strRefId = (string)refId;
    apeDBAdapter.SendEmail(personId, refId, parentReferenceID, customerName, queueId));  
}
希望它有所帮助...

答案 1 :(得分:0)

您可以创建一个方法,该方法从rows集合中获取一系列项目,并根据devision的数量运行多线程。

例如:

SendEmailsToReferencesByRange(int start, int end, DataRowCollection rows)
{
  foreach(var item in rows.Range(start, end-start))
  {
     //Do your sending logic here
  }
}

用法:

//if for example you have 200 items than you can run it in 2 threads
Thread thread = new Thread(()=>SendEmailsToReferencesByRange(0,100, table[0].Rows)).Start();
Thread thread = new Thread(()=>SendEmailsToReferencesByRange(100,200, table[0].Rows)).Start();

答案 2 :(得分:0)

您可以使用此结构来执行此操作。它使用ThreadPool,因此它不会创建很多线程,但更好的想法是使用APM发送电子邮件,因此不会浪费任何线程。

它等待所有后台操作完成。 data是数据集的行。

int opsLeft = data.Count();
using (var mre = new ManualResetEvent(false))
{
    foreach (DataRow row in data)
    {
        string refId = Convert.ToString(row["ReferenceID"]);
        if (!string.IsNullOrEmpty(refId))
        {
            ThreadPool.QueueUserWorkItem(_ =>
            {
                apeDBAdapter.SendEmail(personId, refId, parentReferenceID, customerName, queueId);
                if (Interlocked.Decrement(ref opsLeft) == 0)
                    mre.Set();
            });
        }
        else
        {
            if (Interlocked.Decrement(ref opsLeft) == 0)
                mre.Set();
        }
    }
    mre.WaitOne();
}