Reputation: 49
i have use Sytem.Timers.Timer in service,but is is always shutdown,i don't konw why?please.flow is the code.
public partial class Service1 : ServiceBase
{
List<MyTimer> list = null;
private string tbkqsj = "01:30";
public Service1()
{
InitializeComponent();
Init();
}
public void Init()
{
object o = System.Configuration.ConfigurationManager.AppSettings["Assmebles"];
string[] assmebles = o.ToString().Split(',');
list = new List<MyTimer>();
MyTimer timer = null;
tbkqsj = System.Configuration.ConfigurationManager.AppSettings["tbkqsj"];
int flag = 1;
foreach (var item in assmebles)
{
timer = new MyTimer()
{
Enabled = false,
AutoReset = true,
Interval = 1000 + flag * 100,
};
timer.key = item;
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
this.list.Add(timer);
flag++;
}
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
System.Configuration.ConfigurationManager.RefreshSection("appSettings");
System.Configuration.ConfigurationManager.RefreshSection("connectionStrings");
MyTimer timer = sender as MyTimer;
timer.Enabled = false;
synKqCard.writeMessage("key:"+timer.key+":" + DateTime.Now.ToString());
try
{
if (timer.key == "1")
{
timer.Interval = Convert.ToDouble(System.Configuration.ConfigurationManager.AppSettings["ryInterval"].ToString());
synUser.synUserData();
}
else if (timer.key == "3")
{
timer.Interval = Convert.ToDouble(System.Configuration.ConfigurationManager.AppSettings["DptInterval"].ToString());
synDpt.synDptData();
}
else
{
string hhmm = System.DateTime.Now.ToString("HH:mm");
if (tbkqsj == hhmm)
{
timer.Interval = Convert.ToDouble(System.Configuration.ConfigurationManager.AppSettings["Interval"].ToString());
string SynTime = System.Configuration.ConfigurationManager.AppSettings["SynTime"].ToString();
synKqCard.synKqCardData();
}
}
}
catch (Exception ex)
{
synKqCard.writeMessage("timererror:" + ex);
timer.Enabled = true;
}
timer.Enabled = true;
synKqCard.writeMessage("key:" + timer.key + ":"+timer.Enabled+":" + DateTime.Now.ToString());
}
protected override void OnStart(string[] args)
{
synKqCard.writeMessage(DateTime.Now.ToString()+":start");
foreach (var item in list)
{
item.Enabled = true;
item.Start();
}
}
protected override void OnStop()
{
synKqCard.writeMessage(DateTime.Now.ToString() + ":stop");
foreach (var item in list)
{
item.Enabled = false;
item.Stop();
}
}
}
public class MyTimer : System.Timers.Timer
{
public string key { get; set; }
}
I have initialized three MyTimer
, but run sometimes, one MyTimer
will stop, i look the log,
its like
key:2 2016.06.13 10:12
key: 2 true : 2016.06.13 10:14
it seems it runs fine without errors, but next it has not this MyTimer
's log info. Please help me.
Upvotes: 0
Views: 296
Reputation: 16956
This seems a known issue.
Reference #MS KB Article
In the event handler for the Elapsed event of the Timer object, if you call the Stop method of the Timer object, the reference to the Timer object is lost. The garbage collector then reclaims the memory that is associated with the Timer object. Later, even if you call the Start method of the Timer object to raise the Elapsed event, the call does not work. The Elapsed event is not raised.
As a work around it is advised to use System.Threading.Timer
object instead of the System.Timers.Timer
object.
One more reference (SO Link)-
Windows Service System.Timers.Timer not firing
Upvotes: 0
Reputation: 101156
System.Timer.Timers
will consume any thrown exception that you do not handle. That means that the timer might look like it's running but fails every time the event is triggered.
Thus you need to have a try/catch block in it to see what goes wrong. I strongly recommend that you always use try/catch in thread methods (no matter if it's a explicit thread or invoked through a timer)
Upvotes: 1