我有一个用 C# 编写的 Windows 服务。它还包括一个独立的控制台模式,用于调试目的。它在几乎每台运行它的计算机上都运行良好,但我们遇到了这样的情况:当您尝试启动该服务时该服务被锁定,然后由于超时而被终止。但是在同一台机器上以控制台模式运行它时,它启动正常。
调试起来很痛苦,因为我实际上无法访问正在发生这种情况的机器,我必须通过人工代理。但经过反复调试,我最终将原因缩小到程序集加载。根据日志文件,当它遇到对特定 dll 中任何数据类型的第一个引用时,它就停在那里。它甚至没有给出异常,它只是锁定。
[编辑] 经过进一步检查,它似乎并没有永久锁定,实际完成加载库只需要大约 40 秒,这个时间足以让 Windows 服务决定终止进程。
任何线索如何调试这种情况?
这是我可以用来重现它的最简单的解决方案。 “之前”出现,但“期间”和“之后”不出现。
private static void LoadAssembly()
{
Log("During");
MyNameSpace.MyClass x = new MyNameSpace.MyClass();
}
static void Main(string[] args)
{
try
{
// Leaving out code to handle command line parameters
// ...
//
Log("Before");
LoadAssembly();
Log("After");
if (Environment.UserInteractive)
{
Log("Starting in console mode");
ConnectionManager.Listen();
}
else
{
Log("Starting in service mode");
ServiceBase.Run(new RunAsService());
}
}
catch (Exception ex)
{
Log(ex.ToString());
}
}
最佳答案
该程序集需要 45 秒才能连接,它会尝试连接到 Internet 以在加载程序集之前验证有关该程序集的某些信息,但在该特定计算机上它被防火墙阻止了。尝试启动 30 秒后,Windows 服务管理器放弃并终止进程。
将程序集的加载移动到服务启动后才允许它正常启动(尽管在它开始响应之前有 45 秒的延迟)。
看起来它与生成发布者证据有关。从这里http://msdn.microsoft.com/en-us/library/bb629393.aspx :
We recommend that services use the element to improve startup performance. Using this element can also help avoid delays that can cause a time-out and the cancellation of the service startup.
将以下内容放入 app.config 文件中以消除延迟:
<configuration>
<runtime>
<generatePublisherEvidence enabled="false"/>
</runtime>
</configuration>
关于c# - Windows 服务在程序集加载时锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3293639/