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