Reputation: 691
I have list of ReferenceIDs (string) in a dataset. These ReferenceIDs can have values like this ("CQ1258891","CQ1258892","CQ1258893"....""CQ1258993"). I have a logic in my code to send a mail for each ReferenceIDs.
As of now I am looping through the every ReferenceID synchronously. Due to which, it take more time to send every mail. I have been using .NET 3.0, so I dont have option to use TPL in .NET 4.0.
I have been looking for a multithreaded machanism to send the mails for every ReferenceID asynchronously. As of now, I have tried the following code but it's not working as expected.
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();
}
}
Please share the effective machanism to achieve multithreaded foreach loop for my implementation.
Thanks, Sriram
Upvotes: 0
Views: 1846
Reputation: 4150
You can use this structure to do it. It uses ThreadPool so it's not creating a lot of threads, though better idea will be to use APM to send emails, hence no threads will be wasted.
It waits for all background operations are done. The data
is your dataset's rows.
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();
}
Upvotes: 0
Reputation: 13003
You can create a method that takes a range of items from the rows collection and run it multi-threaded according to the number of devision.
For example:
SendEmailsToReferencesByRange(int start, int end, DataRowCollection rows)
{
foreach(var item in rows.Range(start, end-start))
{
//Do your sending logic here
}
}
Usage:
//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();
Upvotes: 0
Reputation: 2541
Try this
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));
}
hope it helps...
Upvotes: 2