System.Net.Mail.SmtpSender Dispose(bool)的两种不同实现?

时间:2012-08-03 16:39:36

标签: c# asp.net .net decompiling smtpclient

谢天谢地,R#7。如果没有他们新的“反编译来源”功能,我会对如何描述这个问题感到茫然。

我现在有一段SmtpMailSender实现类。以下是它的一些事情:

1。)它不会在开发模式下发送网络邮件。开发web.config看起来像这样:

<smtp deliveryMethod="SpecifiedPickupDirectory">
    <specifiedPickupDirectory pickupDirectoryLocation="App_Data/mail" />
</smtp>
<!--<smtp deliveryMethod="Network">
    <network host="smtp.roadrunner.com" />
</smtp>-->

邮件发送类嗅探SmtpClient.DeliverMethod属性,并配置SmtpClient.PickupDirectoryLocation的实际运行时路径(类似于"C:\path\to\project\App_Data\mail")。

2.)它将所有发送代码包装成一个using语句和一个try块:

...
try
{
    using (var smtpClient = new SmtpClient())
    {
        // detect pickup directory
        // do other encapsulated behaviors
        smtpClient.Send(message);
    }
}
catch (Exception ex)
{
    _exceptionLogger.LogException(ex);
    if (++retryCount  > 2) throw;
    Thread.Sleep(3000);
    Send(message, retryCount); // recursive to same method
}

自去年以来,这一直在我的主工作站上运行良好。我将项目下载到我的笔记本电脑上,并且一直看到每个SmtpClient.Send(MailMessage)导致以下异常:

InvalidOperationException: "The SMTP host was not specified."
at System.Net.Mail.SmtpClient.CheckHostAndPort()
at System.Net.Mail.SmtpClient.get_ServicePoint()
at System.Net.Mail.SmtpClient.Dispose(Boolean disposing)
at System.Net.Mail.SmtpClient.Dispose()
at My.ImplementationOf.SmtpMailSender.Send(MailMessage message, Int32 retryCount)

异常是从SmtpClient.CheckHostAndPort抛出的,根据笔记本电脑上的R#反编译,当SmtpClient.Host属性为null或零长度时抛出异常。我回到我的工作站,发现即使smtpClient.Host属性为null,也没有抛出此异常。

然后我在工作站上为System.Net.Mail.SmtpClient使用了R#的小反编译功能,发现这个类有2种不同的实现!很奇怪,因为对System.dll的引用指向两台机器上的C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.dll!基本上它们是相同的,但有一个重要区别:

protected virtual void Dispose(bool disposing)
{
    // the workstation decompilation shows this:
    if (this.transport != null && this.servicePoint != null)
        this.transport.CloseIdleConnections(this.servicePoint);

    // but the laptop decompilation shows this:
    if (transport != null)
        transport.CloseIdleConnections(ServicePoint);
}

如何才能有两种不同的实施方式?

更新

两台机器都显示了Windows 7 Professional Service Pack 1.我在两者上都运行了Windows Update,两者都告诉我计算机是最新的。我能想到的唯一区别是笔记本电脑的Windows 7尚未激活,我刚刚在3天前安装了它。我想,可以激活操作系统改变框架的System.dll吗?

然后我采取了以下步骤:

  1. 在笔记本电脑上激活Windows
  2. 重新启动
  3. Ran Windows Update,发现一切仍然是最新的。
  4. 运行项目场景,发现仍然抛出相同的异常。

2 个答案:

答案 0 :(得分:1)

可能是因为一台机器有.NET 4.5而另一台机器没有。您是否已将VS2012安装到主工作站上?

此错误已在.NET 4.5中修复:

http://connect.microsoft.com/VisualStudio/feedback/details/618568/smtpclient-and-dispose-without-a-hostname-gives-invalidoperationexception

安装.NET 4.5会在现有的.NET 4.0 dll之上覆盖新的DLL:

http://www.west-wind.com/weblog/posts/2012/Mar/13/NET-45-is-an-inplace-replacement-for-NET-40

答案 1 :(得分:0)

IIRC,框架的服务包不会破坏程序集版本。我可能错了,但我要检查的第一件事是每台机器的服务包级别。

当然,有些修补程序不能像服务包一样清晰显示......