Reputation: 1923
I am using simple method to return data to the Parallel.ForEach
:
private IEnumerable<Recipient> GetRateLimitedResource()
{
IEnumerable<Recipien[]> chunks = _recipients.Chunk(100);
foreach (var r in _recipients)
{
yield return r;
//WHAT HERE
}
}
and then doing something like this:
Parallel.ForEach(GetRateLimitedResource(), po, (Recipient recipient) =>
but how to set some kind of wait here, I mean I would like to chunk _recipients
in the GetRateLimitedResource()
and each chunk send to Parallel.ForEach
with some kind of Thread.Sleep(1000);
Upvotes: 1
Views: 698
Reputation: 2918
As it stands, you could just put your Thread.Sleep
in your loop:
private IEnumerable<Recipient> GetRateLimitedResource()
{
IEnumerable<Recipient[]> chunks = _recipients.Chunk(100);
foreach (var r in _recipients)
{
yield return r;
Thread.Sleep(1000);
}
}
However, the above method will block it's own thread every time you sleep. I would move the 'delay' logic to the method which does the sending, and await Task.Delay()
instead:
private async Task SendEmails()
{
foreach (var chunk in _recipients.Chunk(100))
{
Parallel.ForEach(chunk, po, recipient => ... // your send method here
await Task.Delay(1000);
}
}
There is a potential further optimisation you could make, however. You have not provided the code that actually sends the emails, but sending an email is essentially an asynchronous operation, and would benefit from being written as such. If it were, then the emails could be sent asynchronously rather than in parallel. The code for that would look something like this:
private async Task SendEmails()
{
foreach (var chunk in _recipients.Chunk(100))
{
var sendTasks = new List<Task>();
foreach (var recipient in chunk)
{
sendTasks.Add(SendEmail(recipient)); // your SendEmail method here
}
await Task.WhenAll(sendTasks);
await Task.Delay(1000);
}
}
private async Task SendEmail(string recipient)
{
// your send email logic here
}
Upvotes: 1