I would like for my service to be able to initiate communication with other services.
In order for it to act like a client and start the communication, I thought that an initialized in the constructor timer that calls a method every x seconds could be a good idea.
Is it a bad idea?
I can't see what could be wrong with this approach.
You could utilize System.Timers.Timer - https://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.110%29.aspx
Set its Interval to value at which you want to raise Elapsed event of timer. Subscribe to Elapsed event using an event handler which you implement, in which you would communicate with the external service.
Edit: simple example
class Program
{
private static void timer_ElapsedEventHandler(object sender, EventArgs e)
{
// communicate to external service
Console.WriteLine("ElapsedEventHandler fired");
}
static void Main(string[] args)
{
var timer = new System.Timers.Timer();
timer.Interval = 3000;
timer.Elapsed += timer_ElapsedEventHandler;
timer.Start();
Console.WriteLine("Timer started");
Console.ReadLine();
}
}
Related
I'm trying to figure out how to make it so, after lets say, 1 minute so 60000 milliseconds the console will say hi.
All I have so far is
System.Timers.Timer timer = new System.Timers.Timer(60000);
timer.Start();
But I don't know how to make it so when the timer is done, it will do something.
You can use the elapse event, when 60000 ms has pass the event will be thrown. Example of the elapse event:
class Program
{
static void Main(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer(60000);
timer.Elapsed += new System.Timers.ElapsedEventHandler(elapse); // subscribing to the elapse event
timer.Start(); // start Timer
Console.ReadLine(); // hold compiler until key pressed
}
private static void elapse(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Hy");
}
}
or
void Main()
{
var t = new System.Threading.Timer((s)=>Console.WriteLine("Hi"),null,0,60000);
Console.ReadLine();
}
You can use System.Threading.Thread.Sleep if you only want to do the write once (the timer will run every x seconds):
System.Threading.Thread.Sleep(60000);
Console.WriteLine("something");
What you will want to do is create an event that writes to the console when the timer has elapsed the predefined amount of time.
This is done as follows:
Start by creating your timer and set it to 60s:
var timer = new System.Timers.Timer(60000); //60seconds
Next create an event that will be triggered when the time has elapsed:
private static void MyEvent(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Hello World");
}
Next, bind the timer to that event:
timer.Elapsed += MyEvent;
What this does is tell the computer that when the timer actually starts running in the future and then the timer elapses (60s passes after the timer starts), then the Event called 'MyEvent' will be called which writes to the console.
Finally Start the timer:
timer.Start();
And wait for the even to trigger and write to the console.
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().
I have a problem with a windows service.
protected override void OnStart(string[] args)
{
while (!File.Exists(#"C:\\Users\\john\\logOn\\oauth_url.txt"))
{
Thread.Sleep(1000);
}
...
I have to wait for a particular file, thus while loop is necessary, but the service will not be able to start with loop like this. What I can do to have a running service and a mechanism that checks if a file exists ?
The best option is to have a timer System.Timers.Timer in your service.
System.Timers.Timer timer = new System.Timers.Timer();
In the constructor add the handler for the Elapsed event:
timer.Interval = 1000; //miliseconds
timer.Elapsed += TimerTicked;
timer.AutoReset = true;
timer.Enabled = true;
Then in the OnStart method start that timer:
timer.Start();
In the event handler do your work:
private static void TimerTicked(Object source, ElapsedEventArgs e)
{
if (!File.Exists(#"C:\Users\john\logOn\oauth_url.txt"))
return;
//If the file exists do stuff, otherwise the timer will tick after another second.
}
A minimal service class will look somewhat like this:
public class FileCheckServivce : System.ServiceProcess.ServiceBase
{
System.Timers.Timer timer = new System.Timers.Timer(1000);
public FileCheckServivce()
{
timer.Elapsed += TimerTicked;
timer.AutoReset = true;
timer.Enabled = true;
}
protected override void OnStart(string[] args)
{
timer.Start();
}
private static void TimerTicked(Object source, ElapsedEventArgs e)
{
if (!File.Exists(#"C:\Users\john\logOn\oauth_url.txt"))
return;
//If the file exists do stuff, otherwise the timer will tick after another second.
}
}
I would consider using FileSystemWatcher as that is exactly what it is intended for, to monitor changes on the filesystem. Once event is raised on a folder, you can check if that particular file exists.
The default example in MSDN actually shows monitoring of .txt file https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx
I would like to use a timer instead of sleep within a windows service that should perform an action at a constant interval.
Lets say that I have the following class.
class MailManagerClient
{
//fields
string someString
//Constructor
public MailManagerClient()
{
aTimer = new System.Timers.Timer(30000);
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Enabled = true
}
//methode
public bool DoSomthingIncConstantInterval()
{
//Do Somthing
return true;
}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
DoSomthingIncConstantInterval()
}
}
And I also have a windows service with the OnStart method.
I understand that in the OnStart method I will need to start a new thread for the type MailManagerClient.
But how do I start the thread? Which method should be the entry point for the new thread?
How should the thread stay alive?
Because you are starting the timer in the constructor than all you really need to do is instantiate a MailManagerClient in OnStart. You do not need to manually create a thread because System.Timers.Timer executes the Elapsed event handler on a thread from the ThreadPool.
public class MyService : ServiceBase
{
private MailManagerClient mmc = null;
protected void OnStart(string[] args)
{
mmc = new MailManagerClient();
}
}
I should point out that it would not be obvious to the next programmer looking at your code that MailManagerClient.ctor is actually doing anything. It would be better to define a Start method or something similar that enables the internal timer.
In the OnStart method you could have -
MailManagerClient m;
var th = new Thread(()=>m=new MailManagerClient());
th.Start();
You might also consider defining a Windows Task, as explained in this SO answer: What is the Windows version of cron?. The Windows OS will take care of scheduling and threading.
I have two alternative using timer or using sleep, I need to call a method every 3 seconds after this method is finished, I wrote basic example to demonstrate what I mean:
public static void Main()
{
new Thread(new ThreadStart(fooUsingSleep)).Start();
callToMethodAfterInterval(new Action<object, ElapsedEventArgs>(fooUsingTimer), 3000);
}
public static void fooUsingSleep()
{
Console.WriteLine("Doing some consuming time work using sleep");
Thread.Sleep(3000);
fooUsingSleep();
}
public static void fooUsingTimer(object dummy, ElapsedEventArgs dummyElapsed)
{
Console.WriteLine("Doing some consuming time work usning timer");
callToMethodAfterInterval(new Action<object, ElapsedEventArgs>(fooUsingTimer), 3000);
}
public static void callToMethodAfterInterval(Action<object,ElapsedEventArgs> inMethod, int inInterval)
{
System.Timers.Timer myTimer = new System.Timers.Timer();
myTimer.Elapsed += new ElapsedEventHandler(inMethod);
myTimer.Interval = inInterval;
myTimer.AutoReset = false;
myTimer.Start();
}
So my questions are
1)Can I wrote the code with the timer more elegant? Means removing the call to the callToMethodAfterInterval method from fooUsingTimer, make the timer one or two lines, and remove the dummy variables from the declaration of fooUsingTimer?
2)I understand sleep isn't busy waiting (http://www.codeproject.com/KB/threads/ThreadingDotNet.aspx)
So I don't found justification to use the timer option here, because the sleep is more simple, what is better to use, the timer version or the sleep one?
3)I know that Timers.timer is thread safe, does it can help me in the behavior I want to implement?
Thanks.
Do you realize that fooUsingSleep is calling itself over and over? It will eventually generate a stack overflow.
If you are using timer, it can be as simple as this:
System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
t.Interval = 3000;
t.Tick += new EventHandler((o,ea) => Console.WriteLine("foo"));
The real context of your program matters too.
The sleep option 'wastes' a Thread, not a problem in a small console app but in general not a good idea.
You don't need to restart the timer, the following will keep ticking:
static void Main(string[] args)
{
var t = new System.Timers.Timer(1000);
t.Elapsed += (s, e) => CallMeBack();
t.Start();
Console.ReadLine();
}
Sleep will do the trick, Timer on the other hand has been designed for that exact purpose, conventions are better and they will usually make your code more understandable.