【发布时间】:2019-01-06 10:07:21
【问题描述】:
我有一个托管在 Windows 服务 as described here 中的 WCF 服务。
我已经安排了服务的每晚重启,但有时重启失败并且服务保持/挂起在停止状态并且必须手动终止 EXE 进程。它看起来很可能挂在_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'.等
【问题讨论】:
-
尝试使用Close(TimeSpan timeout)(超时时间小于120s)方法而不是
Close()。如果这有帮助,那么您在 WCF 服务中有长时间运行的任务(Close()等待结束)。这意味着您需要增加 120 秒的 WindowsService 停止超时或处理长时间运行的 WCF 任务。 -
@Reniuz 我认为
scESiftServer.Stop();异步运行只是向Windows 服务系统发送消息。您认为在我的StopService方法中延长间隔或等待服务停止可以解决服务保持在“停止”状态的问题吗? -
增加间隔或关闭 WCF 超时,甚至调用 Abort() 只是为了测试目的。我建议查看 WCF 服务,为什么它没有关闭,你有哪些长时间运行的任务?
-
我在日志中没有看到任何未完成的长时间运行的任务,但它们在服务器上出现了一些网络问题。处于停止状态的服务仍然能够执行未连接到 WCF 服务的任务(定时器任务)。我可以在
es_tracelog.svclog中看到很多异常。 -
@Reniuz 我已经添加了建议的超时,但是即使指定了超时,Close 方法仍然会挂起。挂起的时候没有对服务的请求,只是重启了服务。
标签: c# wcf windows-services