[英]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.