2

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

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

有没有推荐的方法来保持监听器,因此计时器,长时间保持?我们可以定期 ping o1 操作以将其保存在内存中吗?

另外,我在操作 o1 中初始化的计时器变量是一个实例变量,即使侦听器关闭,这个变量是否也应该在内存中(WCF 是单例)?

非常感谢。

代码摘录-

[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 命名空间并增加定时间隔为我修复了它。计时器变量不再消失。

4

2 回答 2

1

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

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

WCF 实例管理

单例服务永远存在,并且只有在主机关闭后才会被处理掉。单例在创建主机时只创建一次。

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

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

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

于 2011-08-15T00:59:39.980 回答
0

我没有专门遇到过这个问题 - 但是,如果您只想在服务运行时运行计时器,为什么不将其设为静态。那么您的实例上下文模式和实例生命周期不会影响您的功能。

于 2011-08-15T07:55:17.137 回答