async / await和IDisposable接口
我有一个实现IDisposable接口的类来处理私有变量_MailMessage
同一个类有一个异步方法,它使用私有IDisposable变量,即async public Task Send
我的问题是:正常的IDisposable实现是否会配置异步方法完成后的私有变量? 这是我正在谈论的课程的一个例子:
public class Email : IEmail { private readonly IEmailData _EmailData; private MailMessage _MailMessage = new MailMessage(); public Email(IEmailData emailData) { if (emailData == null) { throw new ArgumentNullException("emailData"); } if (String.IsNullOrEmpty(emailData.To)) { throw new ArgumentNullException("emailData.To"); } if (String.IsNullOrEmpty(emailData.From)) { throw new ArgumentNullException("emailData.From"); } if (String.IsNullOrEmpty(emailData.FromName)) { throw new ArgumentNullException("emailData.FromName"); } if (String.IsNullOrEmpty(emailData.Subject)) { throw new ArgumentNullException("emailData.Subject"); } if (String.IsNullOrEmpty(emailData.Body)) { throw new ArgumentNullException("emailData.Body"); } _EmailData = emailData; } async public Task Send() { return await Task.Run(() => { using (SmtpClient smtp = new SmtpClient()) { smtp.Send(_MailMessage); } return true; }); } #region "IDisposable implementation" public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~Email() { Dispose(false); } protected virtual void Dispose(bool disposing) { if (disposing) { if (_MailMessage != null) _MailMessage.Dispose(); } } #endregion }
我根据建议不使用析构函数的答案之一更改了IDisposable实现:
#region "IDisposable implementation" public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { if (_MailMessage != null) _MailMessage.Dispose(); } } #endregion
你这样做的根本错误。 一个很好的规则要记住,如果你认为你需要一个析构函数,那么99.9%的时间你就错了。 只有拥有需要释放的非托管类型的私有变量时,才需要析构函数。 你没有。 你可以告诉你做错的方法是当你发现如果处理参数为假,你根本没有做任何事情。 或者换句话说,析构函数实际上并没有做任何事情。 所以不需要它。 那么你也不需要一次性图案。
还有更多的错误,你需要inheritanceIDisposable接口来实现自己的Dispose()方法。 你忘了。
您的Dispose()方法需要由创建Email类实例的客户端代码调用。 您不能自己调用它,您不知道客户端代码何时停止使用您的Email对象。 这是对您的问题的快速回答,您不能将自己置于Send()方法中。 无法保证客户端代码实际上会调用它。 您必须将其留给客户端代码以使其正确。
除了Email.Dispose
之外,我没有看到你明确处理_MailMessage
任何地方。
async
没有做任何与IDispose
特别神奇的IDispose
; 您唯一需要记住的是async
方法可能会提前返回。
所以,如果你这样称呼它:
using (var email = new Email(...)) { await email.Send(); }
然后,在处理email
之前,您的调用代码将(异步)等待Send
完成。 但如果你这样称呼它:
Task task; using (var email = new Email(...)) { task = email.Send(); }
然后,您的呼叫代码将在Send
完成之前处理email
。
上述就是C#学习教程:async / await和IDisposable接口分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1010412.html