谢天谢地,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)
异常是从 抛出的,根据我笔记本电脑上的 R# 反编译,SmtpClient.CheckHostAndPort
当属性为空或零长度时抛出异常。SmtpClient.Host
我回到我的工作站,发现即使该smtpClient.Host
属性为空,也没有抛出此异常。
然后我在工作站上使用了 R# 的小反编译功能System.Net.Mail.SmtpClient
,发现这个类有 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 吗?
然后我采取了这些步骤:
- 在笔记本电脑上激活 Windows
- 重新启动
- 运行 Windows 更新,发现一切仍然是最新的。
- 跑了项目场景,发现还是抛出了同样的异常。