簡體   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