C# - Windows Service, thread, timer - not run - c#

This is my code for Windows Service...but unfortunately, the method myTimer_Elapsed() is invoked only when at least 60 sec. after starting the service. Why not start immediately after switching service?
public partial class MyService : ServiceBase
{
private System.Threading.Thread myWorkingThread;
private System.Timers.Timer myTimer = new System.Timers.Timer();
protected override void OnStart(string[] args)
{
myWorkingThread = new System.Threading.Thread(PrepareTask);
myWorkingThread.Start();
}
private void PrepareTask()
{
myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);
myTimer.Interval = 60000;
myTimer.Start();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
}
void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
..my code to prepare binary db files
BinaryDB rdr = new BinaryDB();
rdr.ReadFile(...)
}
}

It is because the timer interval is set to 1 minute. See the below code in PrepareTask
myTimer.Interval = 60000;
You can set it to any appropriate value. or if you want your code to return once at the start and then after every 60 seconds than you should call it once in OnStart method. Like
protected override void OnStart(string[] args)
{
// Do other initialization stuff...
EvalutateChangeConditions ();
// Create the thread and tell it what is to be executed.
myWorkingThread = new System.Threading.Thread(PrepareTask);
// Start the thread.
myWorkingThread.Start();
}

Related

C# Timer firing too early

When I call the Method random_Start() it works at first: The second console print comes at a reasonable time, but then the gap between the console prints gets smaller and smaller.
After some prints, almost every print comes after way less than 5 Seconds, although the code should set a Timer for at least 5 Seconds, right?
static Timer timer;
static Random random = new Random();
public static void random_Start()
{
timer = new Timer(random.NextDouble()*10000+5000);
timer.Elapsed += OnTimedEvent;
timer.Start();
Console.WriteLine("Start");
}
private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
random_Start();
}
Setup your timer so that you aren't creating a new instance with every timer tick. In the example below, I've disabled AutoReset so that we can set a new interval and start the timer again manually.
static Timer timer;
static Random random = new Random();
public static void random_Start()
{
timer = new Timer(random.NextDouble()*10000+5000);
timer.Elapsed += OnTimedEvent;
timer.AutoReset = false;
timer.Start();
Console.WriteLine("Start");
}
private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
Console.WriteLine("Tick");
timer.Interval = random.NextDouble()*10000+5000;
timer.Start();
}

Setting EditText.Text outside OnCreate

I have a very simple application, currently only containing two classes - these are "MainActivity.cs" and "NewDate.cs"
MainActivity simply hooks up a button and an editText control, then makes a call to "NewDate.NewTimer()" - this just begins a .NET timer instance.
Inside "OnCreate" I am able to set the value of the EditText successfully when the user clicks the button, however, when the timer expires, I call
SafeDate.MainActivity.SetTimerDoneText("Timer done!");
Using breakpoints I can determine that the application is running through "SetTimerDoneText", but the line
editTimerInfo.Text = Text;
does not work.
Any help would be greatly apprecioated.
Both classes below:
MainActivity.cs
public class MainActivity : Activity
{
static EditText editTimerInfo;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
Button btnNewTimer = FindViewById<Button>(Resource.Id.newDate);
editTimerInfo = FindViewById<EditText>(Resource.Id.editTimerInfo);
btnNewTimer.Click += (sender, e) =>
{
// Translate user's alphanumeric phone number to numeric
Core.NewDate.NewTimer();
// editTimerInfo.Text = "Timer started!"; //this works
};
}
public static void SetTimerDoneText(string Text)
{
//SetContentView(Resource.Layout.Main);//commented out - doesn't work
// EditText editTimerInfo = FindViewById<EditText>(Resource.Id.editTimerInfo); //commented out - doesn't work
editTimerInfo.Text = Text;
}
}
NewDate.cs
public static class NewDate
{
public static void NewTimer()
{
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 5000; //Miliseconds : 5000 = 1 second
aTimer.Enabled = true;
}
// Specify what you want to happen when the Elapsed event is raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
SafeDate.MainActivity.SetTimerDoneText("Timer done!"); //Successfully enters the function in MainActivity.cs but won't set the EditText value
}
}
From what I see, you are basically trying to implement a ViewModel pattern.
Since you are a beginner, this may be a bit complex to grasp, but when you are ready, take a look at some tutorial
From now on, go for something much more simple, and put your logic in your Activity
btnNewTimer.Click += (sender, e) =>
{
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 5000; //Miliseconds : 5000 = 1 sec
aTimer.Enabled = true;
};
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
editTimerInfo.Text = "Timer done!"; //Successfully enters the function in MainActivity.cs but won't set the EditText value
}
I have never played with Timers so I cannot guarantee it will work, but this is already better than using statics.
Check if this works for you

System.Timers.Timer() Firing multiple times due to aggregation of Elapsed Events

I want to have a section of my code start a timer once it's called, and I want this timer to keep running until I quit the whole program. My problem is, each time I call OnSomethingHappens() , the Elapsed events aggregate (despite my effort with -= ) and the timer starts firing one extra time (or at least this is what I think is happening). I have also tried defining the timer within the class, to no avail. Here's the related part of my code:
public override void OnSomethingHappens()
{
Timer aTimer= new System.Timers.Timer();
aTimer.Elapsed -= (sender, e) => DoSomethingElse(sender, e);
aTimer.Stop();
aTimer.Close();
aTimer.Elapsed += (sender, e) => DoSomethingElse(sender, e);
aTimer.Interval = 1000;
aTimer.AutoReset = true; // I want the timer to keep working, but only fire once each time
Console.WriteLine("Enabling Timer aTimer");
aTimer.Start();
}
I cannot use static (not sure how that would help but I saw timers being defined as static in many sources) because this class has many instances, and I want them to have separate timers.
Thank you.
Start your timer without the AutoReset and restart it at the end of the DoSomethingElse.
aTimer.AutoReset = false;
aTimer.Start();
DoSomethingElse(..)
{
// do stuff here
aTimer.Start();
}
if each instance of this class uses his own timer , so static is no needed.
private Timer _aTimer;
public void OnSomethingHappens()
{
if (_aTimer != null)
{
_aTimer.Enabled = true; // start timer
return;
}
_aTimer = new System.Timers.Timer();
_aTimer.Elapsed += DoSomethingElse;
_aTimer.Interval = 1000; // every 1 second
_aTimer.Enabled = true; // start timer
}
private void DoSomethingElse(object sender, ElapsedEventArgs e)
{
_aTimer.Enabled = false; // stop timer
// do w/e you want
}
First thing you should really only create once instance of the timer, and hook up one event listener. With your current code, a new timer is being created, with an event listener, every time the method is called. Instead make the timer a class variable, and hook up the event listener in the constructor.
You can start the timer in the OnSomethingHappens, but what do you want to happen on subsequent calls to the method? Should the timer restart, or just continue?
You would probably also want to make the class IDisposable, or at least provide a Stop method to stop the timer when the application closes.
public class MyClass : MyBaseClass, IDisposable
{
private Timer _timer;
private volatile bool _isStopped = true;
public MyClass()
{
_timer = new Timer();
_timer.Interval = 1000;
_timer.Elapsed = OnTimerElapsed;
}
public void Stop()
{
_isStopped = true;
_timer.Stop();
}
public void Dispose()
{
if (_timer != null)
{
Stop();
_timer = null;
}
}
protected override void OnSomethingHappens()
{
if (_timer.Enabled)
{
// Restart or do nothing if timer is already running?
}
else
{
_isStopped = false;
_timer.Start();
}
}
private void OnTimerElapsed(object sender, EventArgs a)
{
if (_isStopped)
{
// If the Stop method was called after the Elapsed event was raised, don't start a long running operation
return;
}
}
}

How to trigger an event every specific time interval in C#?

the timer needs to be run as a thread and it will trigger an event every fixed interval of time. How can we do it in c#?
Here's a short snippet that prints out a message every 10 seconds.
using System;
public class AClass
{
private System.Timers.Timer _timer;
private DateTime _startTime;
public void Start()
{
_startTime = DateTime.Now;
_timer = new System.Timers.Timer(1000*10); // 10 seconds
_timer.Elapsed += timer_Elapsed;
_timer.Enabled = true;
Console.WriteLine("Timer has started");
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
TimeSpan timeSinceStart = DateTime.Now - _startTime;
string output = string.Format("{0},{1}\r\n", DateTime.Now.ToLongDateString(), (int) Math.Floor( timeSinceStart.TotalMinutes));
Console.Write(output);
}
}
Use one of the multiple timers available. Systme.Timer as a generic one, there are others dpending on UI technology:
System.Timers.Timer
System.Threading.Timer
System.Windows.Forms.Timer
System.Web.UI.Timer
System.Windows.Threading.DispatcherTimer
You can check Why there are 5 Versions of Timer Classes in .NET? for an explanation of the differences.
if you need something with mroore precision (down to 1ms) you an use the native timerqueues - but that requies some interop coding (or a very basic understanding of google).
I prefer using Microsoft's Reactive Framework (Rx-Main in NuGet).
var subscription =
Observable
.Interval(TimeSpan.FromSeconds(1.0))
.Subscribe(x =>
{
/* do something every second here */
});
And to stop the timer when not needed:
subscription.Dispose();
Super easy!
You can use System.Timers.Timer
Try This:
class Program
{
static System.Timers.Timer timer1 = new System.Timers.Timer();
static void Main(string[] args)
{
timer1.Interval = 1000;//one second
timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Tick);
timer1.Start();
Console.WriteLine("Press \'q\' to quit the sample.");
while (Console.Read() != 'q') ;
}
static private void timer1_Tick(object sender, System.Timers.ElapsedEventArgs e)
{
//do whatever you want
Console.WriteLine("I'm Inside Timer Elapsed Event Handler!");
}
}

Windows service is not starting after first successfull run

I created a windows service, which will send mails to users based up on some conditions.
I had it installed on server in automatic mode. From the logs i can see that it ran successfully for first time and ended.
And i did not see it running again in the logs after that.
I checked the service in admin tools and it says it is started.
I also restarted service but no use, it did not start again.
Below is the code i used to start the service.
public partial class ScheduledService : ServiceBase
{
Timer timer;
private DateTime lastRun = DateTime.Now;
private DateTime DailyRunTime = Convert.ToDateTime(System.Configuration.ConfigurationManager.AppSettings["DailyRunTime"]);
public ScheduledService()
{
InitializeComponent();
//GetDocRetentionList DocList = new GetDocRetentionList();
//DocList.GetDataSet();
}
protected override void OnStart(string[] args)
{
//System.Diagnostics.Debugger.Launch();
TraceService("start service");
//timer = new Timer(24 * 60 * 60 * 1000);
timer = new Timer(10 * 60 * 1000);
timer.Start();
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
double TimerInterval = Convert.ToDouble(System.Configuration.ConfigurationManager.AppSettings["Timer"]);
timer.Interval = TimerInterval;
timer.Enabled = true;
}
protected override void OnStop()
{
timer.Enabled = false;
TraceService("stopping service");
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
TraceService("Service started at " + DateTime.Now);
if (lastRun.Date < DateTime.Now.Date)
{
if (DateTime.Now > DailyRunTime)
{
GetDocRetentionList DocList = new GetDocRetentionList();
DocList.GetDataSet();
timer.Stop();
lastRun = DateTime.Now.Date;
//timer.Start();
}
}
}
Any help i can get in this regard will be really helpful. Plz let me know.
Well.. your service is set to execute once, then it shuts the timer off in the OnElapsedTime method but never turns itself back on.
The first thing OnElapsedTime should do is turn off the timer. The last thing it should do is turn it back on.

Categories