The MSDN docs for SmptClient say that instance members are not guaranteed to be thread-safe (born out by the use of instance properties to store things like the MailWriter in the reference source).
On the other hand, this post (and my experience) suggests that simply creating and disposing an SmtpClient for each email sent can cause you to hit the connection limit pretty easily.
What's the best way to manage these objects? Do I have to manually create a pool or throttle usage with a semaphore? Or, is there some easier pattern to follow. I'm always using the same mail server.
The posts are indeed on the right track, created a SmtpClient object for every email you send is not the right approach. What I have done is setup a Queue. I have then started a thread which listens for any messages on the queue and sends them off using the same SmtpClient instance. The pseudo-code would be:
Everytime an item is added to the queue you simply SetTheFlag so the thread will start reading the queue again.