0

我在数据集中有 ReferenceID(字符串)列表。这些 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 循环的有效机制。

谢谢,斯里拉姆

4

3 回答 3

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));  
}

希望能帮助到你...

于 2013-10-16T06:46:11.400 回答
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();
}
于 2013-10-16T11:20:34.227 回答
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();
于 2013-10-16T06:46:55.280 回答