Are the SmtpClient.SendMailAsync methods Thread Sa

2019-02-13 21:42发布

The SmtpClient Class states that instance members are not thread safe. This can be seen if concurrent calls are made to Send or SendAsync. Both methods will throw a InvalidOperationException on the second call if the first has not yet completed.

The method SendMailAsync, introduced in .NET 4.5, does not list InvalidOperationException as a thrown exception. Do the new .NET 4.5 methods implement some sort of queuing? Reflector isn't able to shed any light on the implementation details of this class, so I assume this has been implemented in native methods.

Can multiple threads call the SendMessageAsync method on a shared instance of the SMTP client safely?

2条回答
孤傲高冷的网名
2楼-- · 2019-02-13 22:31

I'm not sure why using Reflector didn't work for you. If I decompile it, I see the following code:

[HostProtection(SecurityAction.LinkDemand, ExternalThreading=true)]
public Task SendMailAsync(MailMessage message)
{
    TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
    SendCompletedEventHandler handler = null;
    handler = delegate (object sender, AsyncCompletedEventArgs e) {
        this.HandleCompletion(tcs, e, handler);
    };
    this.SendCompleted += handler;
    try
    {
        this.SendAsync(message, tcs);
    }
    catch
    {
        this.SendCompleted -= handler;
        throw;
    }
    return tcs.Task;
}

As you can see, it's a simple TAP wrapper for SendAsync(). And if SendAsync() throws an exception, SendMailAsync() just rethrows it.

So, the conclusion is that SendMailAsync() is not thread-safe and that its exceptions are underdocumented.

查看更多
▲ chillily
3楼-- · 2019-02-13 22:33

As a note (since I don't have enough points to comment), the traditional way to write an asynchronous operation was to use the Asynchronous Programming Model (APM), but today we typically use the Task-based Asynchronous Pattern (TAP) with its async/await keywords. And although it's not unusual to see TAP wrappers around APM methods, it's also possible to see APM wrappers around TAP methods.

查看更多
登录 后发表回答