我在数据集中有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循环。
谢谢, 斯利拉姆
答案 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();
}