Windows服务中托管的WCF Singleton中的计时器(通过webHttpBinding)意外死亡

时间:2011-08-14 12:38:53

标签: wcf service timer window webhttpbinding

我有一个在Windows服务中托管的WCF服务(在本地系统下运行)。我在里面运行一个System.Timer。初始化Timer的Operation o1 是通过webHttpBinding在http端点上声明的。 我启用了对System.ServiceModel的跟踪,并从.svcLog文件中检查了操作o1的监听持续时间。它表明,在运行大约20个小时后,http端点的Listening才会停止。

我认为这是因为没有传入消息到达该端点。这里的问题是听力停止,我的计时器(在特定的操作 o1 内部初始化)也停止了!

是否有建议的方法来保持监听器,从而使计时器保持较长时间? 我们可以定期ping o1操作以将其保存在内存中吗?

另外,我在Operation o1中初始化的我的timer变量是一个实例变量,即使监听器关闭,这个变量也不应该在内存中(WCF是一个Singleton)?

非常感谢。

代码例外 -

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
public class SchedulerWindows : ISchedulerWindows
{
    ///.........all instance variables.....
    DataTimer timer = null; /**DataTimer wraps a System.Timers timer variable**/
    public List<DataTimer> timersInService = new List<DataTimer>();
    public ISchedulerWindows.o1(string s1, string s2, /*********/)
    {
     //..........//
     timer = new DataTimer();
    }
}

public class DataTimer
    {

        /****Newly introduced System.Threading.Timer, previously I was using        System.Timers.Timer which was dying****/

        public System.Threading.Timer thTimer;
        private static readonly object dbAccessLock = new object();
        private static readonly object thCallbackLock = new object();

        public DataTimer()
        {
        }

        public DataTimer(/************/)
        {            
            TimerCallback timerDelegate = new TimerCallback(this.WorkMethod);
            EventLogLogger l = new EventLogLogger();
            //l.LogMessage("setting up timer ");
            thTimer = new Timer(this.WorkMethod, null, 0, period);
        }
...
}

编辑:从System.Timers命名空间更改为System.Threading命名空间并增加为我修复它的定时间隔。计时器变量不再消失。

2 个答案:

答案 0 :(得分:1)

问题的最可能原因是InstanceContextMode。如果您希望服务实例始终在内存中,则应使用Single。你可能有PerSession或PerCall,这可以解释为什么你的计时器正在消失。你提到你的服务是单身,但症状非常可疑。在关闭主机之前,服务实例将保留在内存中。

[ServiceBehavior(
         ConcurrencyMode = ConcurrencyMode.Multiple, 
         InstanceContextMode = InstanceContextMode.Single
)]

来自WCF instance management

  

单身人士服务永远存在,并且只会被处理掉一次   主机关闭。单个主机在主机时只创建一次   已创建。

编辑:当你的监听器停止监听并且计时器消失时,你可能检查过windows服务是否仍在运行。看看ServiceHost本身是否留在内存中也是有意义的。您还可以在ServiceHosts的“Closing”,“Closed”和“Faulted”事件处理程序中添加一些日志记录。

编辑2: 如果你的计时器消失了,你应该看看你如何分配它。它很可能被垃圾收集。您必须将其声明为可从活动对象访问的实例字段。绝对确定它是静态的。你是为DataTimer做的,但不清楚如何在DataTimer内声明和分配定时器。请发一些代码。

编辑3: 您不应该在操作中创建计时器。如果多次调用操作会发生什么?旧计时器会发生什么?我不知道你是如何关闭/处理它的。您似乎还有两个DataTimer构造函数。其中一个是什么都不做。最重要的是,你有单独的计时器列表。这有点令人费解。请隔离问题,然后在此之后发布新代码。

答案 1 :(得分:0)

我没有特别遇到这个问题 - 但是,如果你只是想在服务运行时运行计时器,那么为什么不让它静止。然后,您的实例上下文模式和实例生命周期不会影响您的功能。