[英]WCF Service hosted in Windows Service hangs on stop
我在Windows服务中托管了WCF服务, 如此处所述 。 我已安排每晚重新启动该服务,但是有时重新启动失败,并且该服务保持/挂起处于“停止”状态,并且必须手动终止EXE进程。 它似乎挂在_ESSServiceHost.Close();
行上_ESSServiceHost.Close();
,因为该行之后没有任何内容记录到日志文件中。 服务很可能在忙时获得停止请求。 而且,由于依赖于services.exe,因此无法杀死基础进程,因此仅服务器重启有效。
这种方法可能有什么问题?
protected override void OnStop()
{
try
{
if (_ESSServiceHost != null)
{
_ESSServiceHost.Close();
_ESSServiceHost = null;
//Never reaches the following line
Tools.LogInfo("Services stopped.");
}
}
catch (Exception ex)
{
Tools.LogError(ex.Message);
}
这是我停止服务的方式:
private bool StopService(ServiceController scESiftServer)
{
int i = 0;
if (scESiftServer.Status == ServiceControllerStatus.Running)
{
try
{
scESiftServer.Stop();
}
catch (Exception ex)
{
Tools.LogEvent("Exception ...");
return false;
}
while (scESiftServer.Status != ServiceControllerStatus.Stopped && i < 120)
{
Thread.Sleep(1000);
scESiftServer.Refresh();
i++;
}
}
if (scESiftServer.Status != ServiceControllerStatus.Stopped)
{
//This line gets executed
Tools.LogEvent("Failed within 120 sec...");
return false;
}
else
{
Tools.LogEvent("OK ...");
}
return true;
}
这样的事情可以帮助吗?
var task = Task.Run(() => _ESSServiceHost.Close(TimeSpan.FromSeconds(299)));
if (!task.Wait(TimeSpan.FromSeconds(300)))
{
_ESSServiceHost.Abort();
}
但是,如果需要,应通过Close方法在内部调用_ESSServiceHost.Abort()。 目标框架是4.5,安装的是.NET 4.7.2。
发现可能是服务在一系列格式错误的请求后挂起。 Expected record type 'Version', found '71'.
等等
在svclog
文件中,我发现服务在一系列格式错误的请求挂起后发生,这些请求在周六和周日大约发生于。 上午5:15。 错误消息为“ Expected record type 'Version', found '71'.
, Error while reading message framing format at position 0 of stream (state: ReadingVersionRecord)
。 但是我找不到导致这些格式错误的请求系列的原因,因此我尝试修复该服务以承受“攻击”。
我修改了OnStop
方法,如下所示:
protected override void OnStop()
{
try
{
if (_ESSServiceHost != null)
{
Tools.LogInfo("Stopping ESService.");
var abortTask = Task.Run(() => _ESSServiceHost.Abort());
var closeTask = Task.Run(() => _ESSServiceHost.Close(TimeSpan.FromSeconds(300)));
try
{
if (_ESSServiceHost.State == CommunicationState.Faulted)
{
Tools.LogInfo("ESSServiceHost.State == CommunicationState.Faulted");
if (!abortTask.Wait(TimeSpan.FromSeconds(60)))
Tools.LogInfo("Failed to Abort.");
}
else
{
if (!closeTask.Wait(TimeSpan.FromSeconds(301)))
{
Tools.LogInfo("Failed to Close - trying Abort.");
if (!abortTask.Wait(TimeSpan.FromSeconds(60)))
Tools.LogInfo("Failed to Abort.");
}
}
}
catch (Exception ex)
{
Tools.LogException(ex, "ESSServiceHost.Close");
try
{
Tools.LogInfo("Abort.");
if (!abortTask.Wait(TimeSpan.FromSeconds(60)))
Tools.LogInfo("Failed to Abort.");
}
catch (Exception ex2)
{
Tools.LogException(ex2, "ESSServiceHost.Abort");
}
}
_ESSServiceHost = null;
Tools.LogInfo("ESService stopped.");
}
}
catch (Exception ex)
{
Tools.LogException(ex,"OnStop");
}
}
今天星期一,我检查了svclog,并在请求中保留了格式错误的“攻击”,但我的服务过得很愉快。 因此,它似乎是固定的。 而且只有:
停止ESService。
ESService已停止。
事件已记录在我的日志文件中。 没有中止等。所以我想将Close
调用放在单独的线程上可以解决问题,但绝对不知道为什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.