Kishore Kumar
Kishore Kumar

Reputation: 12884

Creating Windows Service with Scheduler?

I am creating a Windows Server which will install itself on dobleclick. But i am writing the core code. The problem i am facing is

The windows Server will fetch 10 records from database and upload using a WCF Service. Now after the completing of these 10 records, the service will again look into database and take again 10 records.

But i am also using Timer so that this process will continue every after 5 minutes. Now if at certain time, this upload using WCF took more than 5 Minutes, i have to stop the new execution and wait until it is complete.

How can i perform.

Upvotes: 0

Views: 454

Answers (4)

James
James

Reputation: 82136

This is an ideal scenario for locking. In the below example the callback will trigger every 5 minutes. If the service is still processing a previous batch when the next callback triggers it will simply discard it and try again in 5 minutes time. You can change this to have the callbacks queue up if you prefer, however, you would need to be wary of thread pool starvation if you queue too many.

You could even reduce your interval to say 1 minute to avoid any long delays in the scenario where a batch runs over.

static Timer timer; 
static object locker = new object(); 

public void Start() 
{ 
    var callback = new TimerCallback(DoSomething); 
    timer = new Timer(callback, null, 0, 300000); 
} 

public void DoSomething() 
{ 
    if (Monitor.TryEnter(locker)) 
    { 
       try 
       { 
           // my processing code 
       } 
       finally 
       { 
           Monitor.Exit(locker); 
       } 
    } 
} 

Upvotes: 1

adrianbanks
adrianbanks

Reputation: 83004

Use a Timer to time five minutes, but tell it not to repeat:

timer = new Timer(state => FetchRecords(), null, 
                    new TimeSpan(0, 5, 0), Timeout.Infinite);

This will call the FetchRecords method after five minutes has elapsed, but with not repetition (Timeout.Infinite).

At the end of your FetchRecords method, restart the timer:

timer.Change(new TimeSpan(0, 5, 0), Timeout.Infinite);

This will start the timer going again.

This pattern allows you to have the heartbeat ticking every five minutes so long as the method calls completes within this time, but to not tick if the method call is still in progress.

Upvotes: 0

Gerald Versluis
Gerald Versluis

Reputation: 34118

Why not just set a boolean (or lock even better) when you start doing your thing.

In the loop, check if you boolean (or lock) is active and then skip, so your next batch will run in another 5 minutes.

Upvotes: 0

Amiram Korach
Amiram Korach

Reputation: 13296

Each time the timer ticks, disable it and in the end of the execution enable it again so it will tick again 5 minutes after the end of the last execution.

Upvotes: 3

Related Questions