2

我有一个在 IIS 中运行的 Web 应用程序,并通过托管在同一台计算机上的 WCF 与 Windows 服务进行通信。Windows 服务在内部执行各种工作,有时它非常忙于处理用户请求。一开始我遇到了服务启动的问题,因为有些时间需要很长时间才能启动并最终引发错误,即服务超时。为了解决这个问题,我将代码移动到另一个线程而不是主线程。一切正常,但现在我观察到有时我在服务停止时遇到错误,即

**1053 windows service did not respond in timely fashion**

我的服务 OnStop() 代码:

protected override void OnStop()
        {
            // Stop the WCF service
            if (myServiceHost != null)
            {
                myServiceHost.Close();
                myServiceHost = null;
            }

            // Stop the scheduler

            if (myScheduleManager != null)
            {
                myScheduleManager.Stop();
            }

            // Update the registry value
            Logger.GetInstance().LogEvent(this.GetType().Name, LogLevel.INFO, "Updating registry...");
            Settings.GetInstance().LastStopTime = DateTime.Now.ToString();

            Logger.GetInstance().LogEvent(this.GetType().Name, LogLevel.INFO, "Service stopped.");
        }

它通常发生在服务太忙时。但最终它会在 30-40 分钟后停止。我知道这是由于 Windows 服务中的超时问题而发生的,因为默认时间非常短,并且将其视为超时。

我的问题是避免这种瓶颈的最佳做法是什么意味着我应该将我的 Stop 相关任务移到另一个线程下并进行异步调用以释放该线程中的资源。但是,如果在释放资源期间,用户将启动服务会发生什么?

4

3 回答 3

2

只是一个猜测,但它可能会有所帮助:确保将解决方案配置设置为发布而不是调试。

于 2014-02-23T13:55:51.757 回答
1

只是猜测,但也许有助于追查问题:

你有这个myScheduleManager.Stop(),(我猜)等待进程完成。这很好,但 Windows 只给你 30 秒的执行时间ServiceBase.OnStop()

如果您在此处进行异步处理,您或许可以使用 .NET-Framework 中的 CancellationTokens 来实现 CancellationPattern。

于 2013-03-11T13:38:16.760 回答
1

IsRunning简单的方法可能是您可以确定在您的中构建布尔类型myScheduleManager并在 OnStop() 期间确定

if (myScheduleManager.IsRunning)
    myScheduleManager.Stop();

但是,您有不同的线程完成可能超过 30 秒的进程,但您也可以通过应用来中止您的进程

if (myScheduleManager.IsRunning && !_workerThread.Join(TimeSpan.FromSeconds(30))
    _workerThread.Abort 

myScheduleManager.Stop();

但是,我没有看到完整的代码片段,所以这是我对您的场景的猜测。

于 2013-03-11T13:52:04.053 回答