Send multiple individualised emails via a limited number of SMTP clients
Don't use SmptClient.Send(), use SmptClient.SendMailAsync() instead. It returns a Task..

Actually, I don't think you need this class at all.

(I'm typing in a notepad, so this is untested and just to illustrate the concept.)

var mailTasks = new List&lt;Task&gt;();
var client = new SmtpClient();

foreach(var participant in courseParticipants)
{
    var mail = new MailMessage
    {
        From = new MailAddress("from@example.com"),
        To = participant.email,
        Subject = "come and attend course",
        BodyFormat = MailFormat.Html
    }

    string token = await GetRegistrationTokenAsync(cp);
    mail.Body = $"&lt;div&gt;&lt;a href='example.com/register?userToken='{token}'&gt;let me come&lt;/a&gt;&lt;/div&gt;";

    mailTasks.Add(client.SendMailAsync(mail));
}

try
{
    await Task.WhenAll(mailTasks);
}
catch(AggregateException ex)
{
    //handle failures
}


This code is much simpler to understand, and therefore maintain.



One last thing before I go: Are you absolutely certain that GetRegistrationTokenAsync() will always return a url safe string?


string token = await GetRegistrationTokenAsync(cp);
mail.Body = $"&lt;div&gt;&lt;a href='example.com/register?userToken='{token}'&gt;let me come&lt;/a&gt;&lt;/div&gt;";



You should probably be Url encoding the token.