Parallel.ForEachAsync asynchronously applies an operation to each element of a sequence. It returns immediately with a Task that completes after all iterations finish. section 8.1.4
Listing 8.10 Asyncronous mail merge with the Parallel class
void MailMerge(
string from,
string subject,
string text,
(string email,string name)[] recipients)
{
var processingTasks = new Task[recipients.Length];
Parallel.ForEachAsync(recipients, #1
new ParallelOptions {
MaxDegreeOfParallelism= recipients.Length #2
},
async (current,_) => #3
{
try
{
var sender = new SmtpClient("smtp.example.com");
var message = new MailMessage();
message.From = new MailAddress(from);
message.Subject = subject;
message.To.Add(new MailAddress(current.email));
message.Body = text.Replace("{name}", current.name);
await sender.SendMailAsync(message); #4
}
catch
{
LogFailure(current.email);
}
}).Wait(); #5
}
An asynchronous mail-merge implementation combines Parallel.ForEachAsync with an async lambda and SendMailAsync. ParallelOptions sets the maximum concurrent iterations. section 8.1.4
Use the API with these practical considerations:
- Set MaxDegreeOfParallelism when controlling the number of simultaneous items matters; the default behavior can produce surprising performance. section 8.1.4
- Use the available ParallelOptions support for cancellation and scheduler configuration when the operation requires those controls. section 8.1.4
