Windows Service will not write to log file in loop - c#

I am writing my first windows service and to start with it's just writing to a log file, which is working perfectly. I actually need the service to loop through the entries in a json file, which I have used elsewhere with no issues. So my service initiates a timer, and fires an event every 60 seconds;
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 60000; // 60 seconds
timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
timer.Start();
This works absolutely perfectly and my OnTimer event is thus;
public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
eventLog1.WriteEntry("Drive Space monitoring initiated", EventLogEntryType.Information, eventId++);
}
This puts the entry in the log exactly as I expect every 60 seconds. My problem comes when I try to add a loop to the OnTimer event. For simplicity, here is what I added;
int count = 4;
for(int x = 1; x <= count; x++)
{
string msg = "This is just a counter: " + x.ToString();
eventLog1.WriteEntry(msg, EventLogEntryType.Information, eventId++);
}
This has absolutely no effect and no further entries are added to my log file when the OnTimer event fires.

Use System.Threading.Timer instead of System.Timers.Timer.
System.Timers.Timer gives issue some time when used in windows service and it will swallow all the exceptions.

Related

How do I trigger an event X seconds after a button has been clicked in a Xamarian iOS application?

I am teaching myself C# and, as part of this, am trying to develop an iOS countdown timer app that is to play a .wav sound file X seconds after a timer initiating button has been clicked as the timer value has gone from X to 0.
In an attempt to do this I have tried using the System.Timers namespace but have been unable to figure out how to program the countdown timer described above. Below is my incomplete code (code that obviously does not fulfill the above described function but might be a part of the full code that would fulfill that function):
partial void UIButton1416_TouchUpInside(UIButton sender)
{
url = NSUrl.FromFilename("Sounds/bell.wav");
bell = new SystemSound(url);
int RoundedTimerValue = Convert.ToInt32(Math.Round(TimerSlider.Value, 0));
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 60000;
timer.Enabled = true;
}
Does anyone know how to create the described countdown timer / Trigger an event X seconds after a button has been clicked?
Example Code.
Timer timer = new Timer();
timer.Interval = 60000;
timer.Elapsed += new ElapsedEventHandler((x,y) => {
//Do whatever you want
timer.Stop();
});
Put the below code in the Button Click Handler and make the timer variable global.
timer.Start();
Or you can leave everything in the Button's click handler, not a big deal.
Explanation:
The timer class has an event called Elapsed which is called when the specified number of milliseconds in the timer's Interval gets over. with the line
timer.Elapsed += new ElapsedEventHandler((x,y) => {...
we are assigning a Delegate(Virtual function) to be called when the timer is up. therefore any code within the braces{} will be called at every Timer.Interval milliseconds. we stop the timer at that time as we don't want it to keep running and generate a lot of events.
Update 2:
Normally , EventHandlers are Defined using
return_type functionName(object sender, EventArgs e);
But since the delegate is virtual, so is the parameter. x corresponds to sender and y corresponds to e.
that event handler code can also be written as below
void someFunction(object sender, ElapsedEventArgs e)
{
timer.Stop();
}
and then,
timer.Elapsed += new ElapsedEventHandler(someFunction);
As for the '=>' you can read about Lambda Expressions Here

C# Timer.Elapsed Event firing twice consecutively

I have an application that calls static methods in a DLL every 60 seconds as part of a system "self-check" application. When I manually run the methods, they all complete in less than 10 seconds. My problem is the timer.elapsed event is firing twice, one right after the other. To add to that, for each time the timer elapses, the event fires one more time. (e.g. first time it's 2 firings, second it's 3, third it's 4, etc.) I have tried setting the timer.AutoReset = false along with setting timer.Enabled = false at the beginning of the elapsed event and then setting it to true at the end of the event. I've tried resetting the interval in the event. Every post I have found indicates that the above actions should have resolved this problem. Can anyone help me find what I'm missing?
static Timer cycle = new Timer();
static int cycCount = 0;
static void Main(string[] args)
{
Console.WriteLine("Firebird Survivor Auto Cycle Started.");
Console.CancelKeyPress += Console_CancelKeyPress;
cycle.Interval = 60000; //set interval for service checks.
cycle.Elapsed += new ElapsedEventHandler(CycleComplete_Elapsed);
cycle.AutoReset = false;
cycle.Enabled = true;
cycle.Elapsed += CycleComplete_Elapsed;
while (1 == 1) //stop main method from completing indefinitely
{
//WAIT FOR TIMER TO ELAPSE
}
}
private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
cycle = null;
}
static void CycleComplete_Elapsed(object sender, ElapsedEventArgs e) //method triggered by timer
{
cycle.Enabled = false;
cycCount++;
WormholeServiceControls.CheckWormHoleStatus();
TimeControls.CheckTimePl(); //call time check
PegasusServiceControls.CheckPegasusStatus(null);
Console.Clear();
Console.WriteLine("--------------------------");
Console.WriteLine(String.Format("| Successful Cycles: {0} |", cycCount));
Console.WriteLine("--------------------------");
cycle.Enabled = true;
}
It seems your problem comes from the event handling you are doing. You are assigning the Elapsed event more than one time:
cycle.Elapsed += new ElapsedEventHandler(CycleComplete_Elapsed);
cycle.Elapsed += CycleComplete_Elapsed;
Why this two lines?. You will be all right with only this:
cycle.Elapsed += new ElapsedEventHandler(CycleComplete_Elapsed);

Trigger an Event after x seconds, but also cancel it before it executes

I'm developing an Web API (which works quite well). What's missing?
Here is sample code of Get Action:
public IEnumerable<xxxx> Get()
{
IEnumerable<xxxx> yyyy = new List<xxxx>();
//get yyyy from database
timer = new Timer();
timer.AutoReset = true;
timer.Enabled = true;
timer.Interval = 5000; //miliseconds
timer.Elapsed += timer_Elapsed;
timer.Start();
return yyyy;
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
//code to be executed when timer elapses...
}
So once a request is received, timer will be initialized and will fire Elapsed event at interval of 5 seconds. On next subsequent request this continues....
The expected behavior is such that:
Initialize Request -1
Initialize Timer -1
If another request from same client is received within 5 seconds, timer must not fire elapsed event.
If no request is received from same client within 5 seconds, timer should elapse and fire the event.
Also the timer has nothing to do with client(s).
Here is further business scenario related to this....
I'm developing a Web API that will be consumed by an electronic device when switched on. The device will keep sending it's ON status as long as the power is available. As soon as, user turns off the switch, the request to the server stops.
These status are updated into database whether device is ON or OFF. Now the trickier part was to identify when device turns off (complicated because the server does not know anything if the device stops sending any request). So for each devices there is a separate timer.
First of all, thank you #Patrick Hofman to guide me and think out of box...
I implemented a class having static property inside it.
public class DeviceContainer
{
public static List<DevTimer> timers=new List<DevTimer>();
}
public class DevTimer:Timer
{
public string Identifier {get; set;}
public bool IsInUse{get; set;}
}
and then in above code (in question), I made following changes:
public IEnumerable<xxxx> Get(string Id)
{
//Check if timer exists in
if(!DeviceContainer.timers.Any(s=>s.Identifier.Equals(Id)))
{
//Create new object of timer, assign identifier =Id,
//set interval and initialize it. add it to collection as
var timer = new DevTimer();
timer.AutoReset = true;
timer.Enabled = true;
timer.Interval = 5000; //miliseconds
timer.Elapsed += timer_Elapsed;
timer.IsInUse=true;
timer.Identifier=Id;
DeviceContainer.timers.Add(timer);
timer.Start();
}
else
{
//Code to stop the existing timer and start it again.
var _timer=DeviceContainer.timers.FirstOrDefault(s=>s.Identifier.Equals(Id))
as DevTimer;
_timer.Stop();
_timer.Start();
}
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
//code that will turn off the device in DB
}
I'm not posting the entire code as that's not the purpose here.
I would use Microsoft's Reactive Framework for this.
Here's the code:
IEnumerable<xxxx> yyyy = new List<xxxx>();
Subject<Unit> clientRequestArrived = new Subject<Unit>();
IDisposable subscription =
clientRequestArrived
.Select(_ => Observable.Interval(TimeSpan.FromSeconds(5.0)))
.Switch()
.Subscribe(_ =>
{
//code to be executed when timer elapses...
//directly access `yyyy` here
});
All you need to do is call clientRequestArrived.OnNext(Unit.Default); every time that a user request comes in and that will be enough for this code to reset the timer.
If you want to stop the timer entirely, just call subscription.Dispose().

How I can waiting some time in c# (windows service)

I created windows service on C#.
For now I have methods for scanning DB.
I need call this method two times per minute. Actually I don't know method for waiting in windows service.
I tried Thread.Sleep... but nothing happened.
Please help me with this problem.
private int wait;
protected void Start()
{
wait = 1000;
while (true)
{
if (wait < 30000)
wait += wait;
//implement logic for waiting
Video video = new Video();
video.FindFileForConvert();
if (video.Path != null)
{
Console.WriteLine("video != null. video path = {0}", video.Path);
video.BeginConvertation();
video.DeleteOriginFile();
wait = 1000;
}
}
}
You should use System.Threading.Timer for the same. Since Thread.sleep is not a good practice atleast in some cases.
You may use Timer
public static int Main() {
/* Adds the event and the event handler for the method that will
process the timer event to the timer. */
myTimer.Tick += new EventHandler(TimerEventProcessor);
// Sets the timer interval to 5 seconds.
myTimer.Interval = 5000;
myTimer.Start();
// Runs the timer, and raises the event.
while(exitFlag == false) {
// Processes all the events in the queue.
Application.DoEvents();
}
return 0;
}
I may be mistaken, but I think that this code will help you resolve your problem. DispatcherTimer
DispatcherTimer dispathcerTimer = new DispatcherTimer();
dispathcerTimer.Interval = TimeSpan.FromMinutes(2);
dispathcerTimer.Tick += dispathcerTimer_Tick;
dispathcerTimer.Start();
void dispatcherTime_Tick(object sender, object e)
{
//function, which needs to be invoked every two minutes.
}

Changing Time On MaskedTextbox

I want to design changing time on maskedtextbox in my application like windows where time changes on every second. I have set maskedtexbox1 as below:
maskedTextBox1.Text = DateTime.Now.ToShortTimeString();
which is showing current system short time but it’s not changing on every second like windows. How to do?
I'm on Visual Studio 2005, and .NET is below 3.5.
I'd use the timer and fire an event every second to update the time.
Create a timer (an instance of class Timer in the package System.Windows.Forms).
Set its frequency to 1 second (i.e. 1000 milliseconds).
Tell it what method to call when it goes off (the event handler Kaboom).
Somewhere in your executable code you do that by typing the following.
Timer ticker= new Timer();
ticker.Interval = 1000;
ticker.Tick += new EventHandler(Kaboom);
In the same class (or, if you're confident how to do it, somewhere where you can reach the code) you also create the handler for the fired event of ticking, so that the promise you made about a method to be called when the timer goes off is kept.
private void Kaboom(Object sender, EventArgs eventArgs)
{
// Execute the tickability code
MaskedTextBox1.Text = DateTime.Now.ToShortTimeString();
}
Also, don't forget to actually start your ticker when you feel that you're ready.
MyTimer.Start();
Tada!
EDIT:
For the sake of completeness, I'm also going to paste in a part of the reply of #CuaonLe (a higher threshold of competence and requirement for .NET 3.5 or newer).
Timer timer = new Timer { Interval = 1000 };
timer.Tick += (obj, args)
=> MaskedTextBox1.Text = DateTime.Now.ToLongTimeString();
timer.Start();
I guess you'll need to setup a Timer which updates your maskedTextBox1 every second.
For how to do that, please see: Add timer to a Windows Forms application
Cheers. Keith.
You can use System.Windows.Forms.Timer to update textbox value every second for example:
var timer = new Timer();
timer.Interval = 1000;
timer.Tick += delegate
{
textBox1.Text = DateTime.Now.ToLongTimeString();
};
timer.Start();

Categories

Resources