繁体   English   中英

如何每5秒调用一次方法?

[英]How to call a method in every 5 seconds?

我有两个wcf服务Client.svc和Admin.svc。 客户端中的方法每5秒钟调用一次admin服务方法。 客户端调用的Admin方法将验证如果在5秒内未调用此方法,则更新状态为“ NotResponding”的数据库,否则将其更新为“ IsAlive”值。

所有这些都应该在单独的线程上完成。

我编写了一些代码,其中Client使用Timer每5秒调用一次该方法。

    public static void RegisterHeartBeat(PingRequest pingRequest)
    {
        try
        {

            string heartBeatInterval = Phoenix.API.Utility.ConfigReader.GetAppSettingsValue("HeartBeatInterval");
            int timeInSeconds = -1;

            Int32.TryParse(heartBeatInterval, out timeInSeconds);

            if (timeInSeconds != -1)
            {
                TimerCallback timerCallHeartBeat = new TimerCallback(CallRegisterHeartBeat);
                Timer timer = new Timer(timerCallHeartBeat, pingRequest, 0, (timeInSeconds * 1000)); //Multiplying by 1000, converts seconds to milliseconds
            }
            else
            {
                Exception ex = new Exception("HeartBeatInterval is not configured in web.config file");
                Phoenix.Client.API.BLL.Common.CommonUtility.CreateResultAndLogClientException(null, null, ex);
            }
        }
        catch (Exception ex)
        {
            Phoenix.Client.API.BLL.Common.CommonUtility.CreateResultAndLogClientException(null, null, ex);
        }

    }


    private static void CallRegisterHeartBeat(object state)
    {
        PhoenixClientBLL.Admin.InternalClient internalClient = new PhoenixClientBLL.Admin.InternalClient("BasicHttpBinding_IInternal");

        if (state != null)
        {
            //AdminAPI accepts Admin.PingRequest parameter which has a different format than ClientAPI PingRequest. 
            //Thus, a new object of admin ping request type is created.
            Phoenix.API.ClientServiceContracts.DataContracts.PingRequest pingRequestDC = state as Phoenix.API.ClientServiceContracts.DataContracts.PingRequest;

           //AdminAPI
            PhoenixClientBLL.Admin.PingRequest pingRequest = new PhoenixClientBLL.Admin.PingRequest();

            //Test Agent ID
            pingRequest.TestAgentId = Guid.Parse(pingRequestDC.TestAgentId);

            //Test Agent Status is not set because it will be decided in ADMIN API as per the interval difference.
            internalClient.RegisterHeartBeat(pingRequest);

        }

    }

在“管理员”中,我检查上次更新日期和当前日期以及更新数据库的时间差。

    public static void RegisterHeartBeat(PingRequest pingRequest)
    {
        int status = 0;
        DateTime startTime, endTime;
        int testAgentId = -1;
        string heartBeatIntervalValue = Phoenix.API.Utility.ConfigReader.GetAppSettingsValue("HeartBeatInterval");
        int heartBeatInterval = -1;

        if(String.IsNullOrEmpty(heartBeatIntervalValue))
        {
             Common.CommonUtility.CreateResultAndLogException(null, null, new Exception("HeartBeatInterval is not configured in the configuration file"));
        }
        else
        {
                try
                {
                    string key = pingRequest.TestAgentId.ToString();
                    if (!String.IsNullOrEmpty(key))
                    {
                        if (!heartBeatTimeStamp.ContainsKey(key))
                        {
                            heartBeatTimeStamp.Add(key, System.DateTime.Now);
                        }
                        else
                        {

                            endTime = DateTime.Now;
                            if (heartBeatTimeStamp[key].HasValue)
                            {
                                startTime = heartBeatTimeStamp[key].Value;
                                var timeDiff = new TimeSpan(endTime.Ticks - startTime.Ticks);

                                //Check the configured heart beat interval value
                                Int32.TryParse(heartBeatIntervalValue, out heartBeatInterval);

                                if (heartBeatInterval != -1)
                                {
                                    if (timeDiff.Seconds > heartBeatInterval)
                                    {
                                        // add update NotResponding = 3 ..
                                        Int32.TryParse(pingRequest.TestAgentId.ToString(), out testAgentId);

                                        //If Test Agent ID is converted into integer than update table else log the error.
                                        if (testAgentId != -1)
                                        {
                                            status = DAO.TestAgentDAO.RegisterHeartBeat(testAgentId, (int)TestAgentStatus.NotResponding);
                                        }
                                        else
                                        {
                                            Common.CommonUtility.CreateResultAndLogException(null, null, new Exception("Cannot convert Test Agent ID Data type from GUID to Integer"));
                                        }

                                        //Sql Error
                                        if (0 != status)
                                        {
                                            Common.CommonUtility.CreateResultAndLogSqlError(null, status, null);

                                        }
                                    }
                                    else
                                    {
                                        // add update IsAlive= 4
                                        Int32.TryParse(pingRequest.TestAgentId.ToString(), out testAgentId);

                                        //If Test Agent ID is converted into integer than update table else log the error.
                                        if (testAgentId != -1)
                                        {
                                            status = DAO.TestAgentDAO.RegisterHeartBeat(testAgentId, (int)TestAgentStatus.IsAlive);
                                        }
                                        else
                                        {
                                            Common.CommonUtility.CreateResultAndLogException(null, null, new Exception("Cannot convert Test Agent ID Data type from GUID to Integer"));
                                        }

                                        //Sql Error
                                        if (0 != status)
                                        {
                                            Common.CommonUtility.CreateResultAndLogSqlError(null, status, null);

                                        }
                                    }
                                }
                                else
                                {
                                    Common.CommonUtility.CreateResultAndLogException(null, null, new Exception("Invalid HeartBeatInterval Value"));
                                }


                            }
                        }
                    }
                    else
                    {
                        Common.CommonUtility.CreateResultAndLogException(null, null, new Exception("Test Agent ID is incorrect or does not exists"));
                    }
                }
                catch (Exception ex)
                {
                    Common.CommonUtility.CreateResultAndLogException(null, null, ex);

                }
        }


    }

但是我的计时器行为异常,从不调用admin方法。.请问为什么? 或任何其他逻辑都需要在这里实现。

谢谢普里扬卡

您可能可以使用调度程序而不是计时器。 有一个可用于.NET的开源调度程序Quartz .Net 这可以每5秒触发一次呼叫。

您在任何地方启动计时器吗? 还是将“启用”设置为true?

http://msdn.microsoft.com/zh-CN/library/system.timers.timer.start.aspx

在您的静态主类中实例化一个计时器,并为该计时器创建一个经过的事件处理程序,以在5秒钟结束时转到该计时器。

在过去的事件处理程序中,每5秒调用一次您要运行的方法。 请记住,计时器和事件处理程序跨越线程,因此您需要意识到可能同时发生两个事件-这意味着在thead安全管理器中的代码...

计时器示例http://msdn.microsoft.com/zh-cn/library/system.timers.timer(v=VS.71).aspx

我只是重新阅读了您的帖子,您正在使用计时器...请记住THREADSAFE。 如果您需要先停止计时器再进入需要经过的方法,甚至在经过时调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM