  		}
  	}
 diff --git a/MimeKit/MessagePart.cs b/MimeKit/MessagePart.cs
-index 9376b21..6bb743d 100644
+index 01e635e3..bbcc99c5 100644
 --- a/MimeKit/MessagePart.cs
 +++ b/MimeKit/MessagePart.cs
-@@ -203,5 +203,23 @@ namespace MimeKit {
+@@ -139,6 +139,11 @@ namespace MimeKit {
+ 		{
+ 		}
+ 
++		void CheckDisposed ()
++		{
++			CheckDisposed (nameof (MessagePart));
++		}
++
+ 		/// <summary>
+ 		/// Gets or sets the message content.
+ 		/// </summary>
+@@ -165,11 +170,16 @@ namespace MimeKit {
+ 		/// <exception cref="System.ArgumentNullException">
+ 		/// <paramref name="visitor"/> is <c>null</c>.
+ 		/// </exception>
++		/// <exception cref="System.ObjectDisposedException">
++		/// The <see cref="MessagePart"/> has been disposed.
++		/// </exception>
+ 		public override void Accept (MimeVisitor visitor)
+ 		{
+ 			if (visitor == null)
+ 				throw new ArgumentNullException (nameof (visitor));
+ 
++			CheckDisposed ();
++
+ 			visitor.VisitMessagePart (this);
+ 		}
+ 
+@@ -186,11 +196,16 @@ namespace MimeKit {
+ 		/// <para>-or-</para>
+ 		/// <para><paramref name="constraint"/> is not a valid value.</para>
+ 		/// </exception>
++		/// <exception cref="System.ObjectDisposedException">
++		/// The <see cref="MessagePart"/> has been disposed.
++		/// </exception>
+ 		public override void Prepare (EncodingConstraint constraint, int maxLineLength = 78)
+ 		{
+ 			if (maxLineLength < FormatOptions.MinimumLineLength || maxLineLength > FormatOptions.MaximumLineLength)
+ 				throw new ArgumentOutOfRangeException (nameof (maxLineLength));
+ 
++			CheckDisposed ();
++
  			if (Message != null)
- 				Message.WriteTo (options, stream, cancellationToken);
+ 				Message.Prepare (constraint, maxLineLength);
+ 		}
+@@ -210,6 +225,9 @@ namespace MimeKit {
+ 		/// <para>-or-</para>
+ 		/// <para><paramref name="stream"/> is <c>null</c>.</para>
+ 		/// </exception>
++		/// <exception cref="System.ObjectDisposedException">
++		/// The <see cref="MessagePart"/> has been disposed.
++		/// </exception>
+ 		/// <exception cref="System.OperationCanceledException">
+ 		/// The operation was canceled via the cancellation token.
+ 		/// </exception>
+@@ -255,6 +273,9 @@ namespace MimeKit {
+ 		/// <para>-or-</para>
+ 		/// <para><paramref name="stream"/> is <c>null</c>.</para>
+ 		/// </exception>
++		/// <exception cref="System.ObjectDisposedException">
++		/// The <see cref="MessagePart"/> has been disposed.
++		/// </exception>
+ 		/// <exception cref="System.OperationCanceledException">
+ 		/// The operation was canceled via the cancellation token.
+ 		/// </exception>
+@@ -278,5 +299,23 @@ namespace MimeKit {
+ 
+ 			await Message.WriteToAsync (options, stream, cancellationToken).ConfigureAwait (false);
  		}
 +
 +		/// <summary>

+						throw;
+					}
 
 					if (view.BaseUri != null)
 						part.ContentLocation = view.BaseUri;
@@ -2739,7 +2800,13 @@ namespace MimeKit {
 						related.Add (part);
 
 						foreach (var resource in view.LinkedResources) {

+		}
+
+		/// <summary>
+		/// Releases all resources used by the <see cref="MimeEntity"/> object.
+		/// </summary>
+		/// <remarks>Call <see cref="Dispose()"/> when you are finished using the <see cref="MimeEntity"/>. The
+		/// <see cref="Dispose()"/> method leaves the <see cref="MimeEntity"/> in an unusable state. After
+		/// calling <see cref="Dispose()"/>, you must release all references to the <see cref="MimeEntity"/> so
+		/// the garbage collector can reclaim the memory that the <see cref="MimeEntity"/> was occupying.</remarks>
+		public void Dispose ()
+		{
+			Dispose (true);
+			isDisposed = true;
+			GC.SuppressFinalize (this);
+		}
+
+		#endregion
+
 		/// <summary>
 		/// Load a <see cref="MimeEntity"/> from the specified stream.
 		/// </summary>
diff --git a/MimeKit/MimeMessage.cs b/MimeKit/MimeMessage.cs
index 96677c01..c135f5d1 100644
--- a/MimeKit/MimeMessage.cs
+++ b/MimeKit/MimeMessage.cs
@@ -61,7 +61,7 @@ namespace MimeKit {
 	/// tree of MIME entities such as a text/plain MIME part and a collection
 	/// of file attachments.</para>
 	/// </remarks>
-	public class MimeMessage
+	public class MimeMessage : IDisposable
 	{
 		static readonly HeaderId[] StandardAddressHeaders = {
 			HeaderId.ResentFrom, HeaderId.ResentReplyTo, HeaderId.ResentTo, HeaderId.ResentCc, HeaderId.ResentBcc,
@@ -262,6 +262,19 @@ namespace MimeKit {
 			MessageId = MimeUtils.GenerateMessageId ();
 		}
 
+		/// <summary>
+		/// Releases unmanaged resources and performs other cleanup operations before the
+		/// <see cref="MimeMessage"/> is reclaimed by garbage collection.
+		/// </summary>
+		/// <remarks>
+		/// Releases unmanaged resources and performs other cleanup operations before the
+		/// <see cref="MimeMessage"/> is reclaimed by garbage collection.
+		/// </remarks>
+		~MimeMessage ()
+		{
+			Dispose (false);
+		}
+
 		/// <summary>
 		/// Get or set the mbox marker.
 		/// </summary>
@@ -2595,6 +2608,39 @@ namespace MimeKit {
 			}
 		}
 
+		#region IDisposable implementation
+
+		/// <summary>
+		/// Releases the unmanaged resources used by the <see cref="MimeMessage"/> and
+		/// optionally releases the managed resources.
+		/// </summary>
