-1

In C# I would like to run a method every 30 seconds. For example, in a while loop it would run ReadData() every 30 seconds. ReadData goes out to collect data, analyzes, and stores it.

I understand that Thread.Sleep would pause the thread and the UI. Which for a few milliseconds might not be an issue, but for 30 seconds it definitely would. Is there another way to do this.

The limitation is that the application must be run using .NET 4.0 or less.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
mgalal
  • 427
  • 12
  • 24
  • 1
    why don't you use a Timer? – Daniel A. White Jul 08 '14 at 23:37
  • Use a timer. If you need to, combine it with a semaphore to prevent multiple operations in parallel. – Casey Jul 08 '14 at 23:38
  • 1
    Please don't just ask us to solve the problem for you. Show us how _you_ tried to solve the problem yourself, then show us _exactly_ what the result was, and tell us why you feel it didn't work. See "[What Have You Tried?](http://whathaveyoutried.com/)" for an excellent article that you _really need to read_. – John Saunders Jul 08 '14 at 23:39
  • I did, I use Thread.Sleep usually, but for 30 second delay it locks my UI. – mgalal Jul 09 '14 at 21:30

3 Answers3

2

It sounds like you are doing some sort of polling at a fixed interval which is easy enough to implement with a timer as described in my example bellow. However, one thing to think about is the unnecessary overhead of polling in general. As an alternative I would like to suggest an asynchronous solutions instead where you only need to react to events when they occur and not on a fixed schedule. A typical implementation of this in the .Net realm is queue based systems, and a great product that makes this really easy is NServiceBus.

Anyway, bellow is the timer code:

Here is an example of a timer from msdn

http://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx

public class Example
{
   private static Timer aTimer;

   public static void Main()
   {
        // Create a timer with a two second interval.
        aTimer = new System.Timers.Timer(2000);
        // Hook up the Elapsed event for the timer. 
        aTimer.Elapsed += OnTimedEvent;
        aTimer.Enabled = true;

        Console.WriteLine("Press the Enter key to exit the program... ");
        Console.ReadLine();
        Console.WriteLine("Terminating the application...");
   }

    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
    }
}
TGH
  • 38,769
  • 12
  • 102
  • 135
  • There are several choices [outlined in this question](http://stackoverflow.com/questions/1416803/system-timers-timer-vs-system-threading-timer) – Casey Jul 08 '14 at 23:41
  • @emodendroket Updated with yet another alternative - queues :-) – TGH Jul 09 '14 at 00:01
  • Thank you very much for the example and link. I will also look at your other suggestion of reacting as events occur. I did not think of that as an option, but it could work. Thanks again – mgalal Jul 09 '14 at 21:33
0

Use Reactive Extensions, placing the ReadData method in a background thread:

Install-Package Rx-Main

var subscription = Observable.Interval(TimeSpan.FromSeconds(30)).Subscribe(_=>{ ReadData(); });

When you no longer need it, dispose it.

Darek
  • 4,687
  • 31
  • 47
0

The other two answers are great if you're looking for something that will run while, say, a user is on the program, and I notice you're worried about blocking the UI thread so it sounds like that's the case, but just for the record if you're looking for something to be always running, you might want to look into the built-in Windows task scheduling services.

Again, definitely not your solution if you just want to, say, update a dashboard every thirty seconds. But if you're worried about updating a database or something server-side, then you probably shouldn't write your own service with a task running in the background and hitting every thirty seconds. That's a better thing to let Windows coordinate.

Matthew Haugen
  • 12,916
  • 5
  • 38
  • 54