Windows Service中托管的WCF服务停止停止

时间:2018-07-30 07:44:46

标签: c# wcf windows-services

我在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'.

1 个答案:

答案 0 :(得分:0)

我在svclog文件中发现,在星期六和星期天大约在大约1点钟发生一系列错误的请求之后,我的服务挂起了。上午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调用放在单独的线程上可以解决此问题,但绝对不知道为什么。