WCF服务和计时器不配合 [英] WCF service and Timer don't cooperate

查看:193
本文介绍了WCF服务和计时器不配合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WCF服务,其中包含一种写入事件日志的方法和一个计时器.当我安装该服务并启动它时,我的一些调试消息将写入事件日志,但不是全部.它将显示我的OnStart()方法中的前几条调试消息,然后它显示了我的服务已启动的条目……此后什么也没有,尽管我在调试消息之间调用了一个计时器(并且这些调试消息已写入事件日志中)所以我知道计时器已启动...或者应该是...)

这显然是位于我的服务组件中的我的OnStart:

I have a WCF service that contains a method to write to the event log, and a timer. When I install the service and start it, some of my debug messages are written to the event log, but not all. It will show my first few debug messages from my OnStart() method, then it has an entry that my service has started... nothing after that although I call a timer between debug messages (and those debug messages are written to the event log so I know the timer is started... or should be...)

Here''s my OnStart that resides in my service component obviously:

protected override void OnStart(string[] args)
        {
            //timer1.Enabled = true;
            //Code for when the service starts
            string logString = "Success writing to the EventLog - oooooh ya!";
            //Clear the variables
            currentSessionUserAccount = "";
            currentSessionUserName = "";
            currentConnectionState = "";
            machineName = Dns.GetHostName();
            currentStationName = "";
            WriteLog.WriteString(logString);
            //Call Timer
            TimerTick.StartTheTimer();   

            logString = "Account: " + currentSessionUserAccount +
                    "Name: " + currentSessionUserName +
                    "State: " + currentConnectionState + "Machine: " + machineName +
                    "Station: " + currentStationName;


            FuncToCall func = new FuncToCall(WriteLog.WriteString);
            IAsyncResult iar = func.BeginInvoke(logString, null, null);
            func.EndInvoke(iar);         
        }




这是我知道的计时器代码,因为"Entered TimerTick Main"被写入事件日志而被调用:




Here''s my timer code that I know gets called because "Entered TimerTick Main" is written to the event log:

static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();

        private static void TimerEventProcessor(Object sender, EventArgs myEventArgs)
        {
            CheckDevices();
        }

        public static void StartTheTimer()
        {
            WriteLog.WriteString("Entered TimerTick Main");
            myTimer.Tick += new EventHandler(TimerEventProcessor);

            myTimer.Interval = 5000;
            myTimer.Start();
        }

        public static void CheckDevices()
        {
            WriteLog.WriteString("Checking Devices...");
        }
    }
}



因此,在我的事件日志中,我具有这三个条目,从最旧到最新列出:
成功写入EventLog-oooooh ya!
输入TimerTick Main
帐户:名称:状态:机器:182498672203:
服务已成功启动.

就是这样...我感到困惑的是,一旦服务启动",为什么计时器似乎停止了?



So in my event log, I have these three entries, listed from oldest to newest:
Success writing to the EventLog - oooooh ya!
Entered TimerTick Main
Account: Name: State: Machine: 182498672203:
Service started successfully.

And that''s it... What I''m confused about is why does my timer seem to stop once the service is ''Started''? Any help and/or guidance would be greatly appreciated!

推荐答案

您是认真的吗?服务应用程序是什么System.Windows.Forms.Timer计时器?

即使在Forms应用程序中,此计时器类也确实很糟糕,而且非常不准确.它的唯一好处是它与Forms UI一起使用的简便性-它的Tick事件处理程序不需要UI线程调用(您的处理程序总是在UI线程中调用),但是只有在精度要求不高的情况下才可以使用它;例如,它不能合理地用于动画.

使用其他两个Timer类之一,即System.Threading.TimerSystem.Timers.Timer.

参见:
http://msdn.microsoft.com/en-us/library/system.threading. timer.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/system.timers. timer.aspx [ ^ ].

您没有解释使用计时器的目的.因此,请认真考虑使用其他线程而不是计时器.例如,与基于计时器的方法相比,使用单独的线程和线程同步原语来执行周期性操作通常更易于实现和调试,更直接,更可靠.提示:您是否考虑过当新事件到来时仍在执行计时器事件处理程序或计时器回调的情况?您可以处理它,但是它比使用线程方法要复杂得多.

请查看我过去关于线程的解决方案以获取更多详细信息:
如何获取keydown事件在vb.net中的不同线程上操作 [启用禁用+多线程后控件事件不会触发 [ ^ ].

—SA
Are you serious? What System.Windows.Forms.Timer timer is service application?

Even in Forms application, this timer class is really bad and ridiculously inaccurate. It''s only benefit is simplicity of its use with Forms UI — its Tick event handler does not require UI thread invocation (your handler is always called in your UI thread), but it can be used only if accuracy is not critical; for example, it cannot be reasonably used for animation.

Use one of the two other Timer classes, either System.Threading.Timer or System.Timers.Timer.

See:
http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx[^],
http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx[^].

You did not explain the purpose of using a timer. So, seriously consider using additional thread instead of timer. For example, implementing periodic action using a separate thread and thread synchronization primitives is often easier to implement and debug, more straightforward and reliable compared with timer-based approach. On hint: did you consider dealing with situations when a timer event handler or a timer callback is being still executed when a new event comes? You can deal with it, but it is much more tricky than with a thread approach.

Please see my past solutions on threading for more detail:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA


这篇关于WCF服务和计时器不配合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆