-1

I'm trying to replace Thread.Sleep with System.Threading.Timer, and I'm trying to implement it in the following code. The main reason for changing is that, even though it works when testing locally, it's not working properly in the server. Plus, I've read that using it here is bad practice.

I've seen several examples (including the one below), but I'm not certain how I could use it in my case: System.Threading.Timer in C# it seems to be not working. It runs very fast every 3 second

In my console app, I need to copy files to our server every 15 minutes. So at :20, :35, :50, :05, I begin reading files for that quarter. In the case below, the files will be available at :45, and I add 5 minutes just in case.

This is my code. I had previously tried to copy files from several quarters in parallel, but the server where the source files reside is having trouble with that. So I'm going back to this.

My question is, how can I replace Thread.Sleep with System.Threading.Timer in this example?

I wanted to try await Task.Delay(Int32), but I have VS2010:

DateTime lastTimeRead = new DateTime(2014, 9, 9, 8, 35, 0);  //Last read at 8:35AM
DateTime nextTimeRead; 
for (; ; )
{
    now = DateTime.Now;  //It's currently 8:43AM
    nextTimeRead = LastTimeRead.AddMinutes(15);  // nextTimeRead = 8:50AM.
    if (nextTimeRead > now) //Yes, so wait 7 minutes for files to be available
    {
        TimeSpan span = nextTimeRead.Subtract(now);
        Double milliseconds = span.TotalMilliseconds;
        Console.WriteLine("Sleep for milliseconds: " + milliseconds.ToString());
        Thread.Sleep(Convert.ToInt32(milliseconds));
        Console.WriteLine("Download files after sleep of: " + nextTimeRead.ToString());
        DownloadFilesByPeriod(nextTimeRead);
    }
    else // Files are available. Read.
    {
        Console.WriteLine("Download files no sleep: " + nextTimeRead.ToString());
        DownloadFilesByPeriod(nextTimeRead);
    }
    LastTimeRead = nextTimeRead;
}
Community
  • 1
  • 1
Joe_Hendricks
  • 746
  • 4
  • 16
  • 1
    Windows has a `Task Scheduler`, if your pattern is really that simple, maybe it's easier to worry about your programs internal logic and leave the starting to windows. That's already well tested and working. – nvoigt Sep 09 '14 at 14:26
  • As you have posted your code that uses `Thread.Sleep` it is not clear what problems you had with using a timer. What issue did you have using a timer that fires every 15 minutes and starts at the appropriate starting point? – Daniel Kelley Sep 09 '14 at 14:27
  • Are you asking where to download "VS Express 2013 for desktop"? – Alexei Levenkov Sep 09 '14 at 14:28
  • I apologize for not being clear, I'll edit the question. – Joe_Hendricks Sep 09 '14 at 14:29
  • 1
    Instead of the downvotes, can you let me know what I need to change to make it a good question? – Joe_Hendricks Sep 09 '14 at 14:41
  • 1
    vmgmail - I would think that @DanielKelley's comment is very clear... You said you have problem with `Timer`-based code, but sample shows no traces of it... – Alexei Levenkov Sep 09 '14 at 15:30
  • I have to admit that I didn't try it in my code. The reason is that I wasn't sure how to fill the last two parameters of the Timer constructor. It has an `initial wait period` and a `subsequent wait period`, and I wasn't sure how to apply those. – Joe_Hendricks Sep 09 '14 at 15:38
  • I will edit the code and the question to make it clearer. – Joe_Hendricks Sep 09 '14 at 15:44
  • @vmgmail Update your question and include that. That is the key to what you are asking. The subsequent wait period is simple - 15 minutes. The first depends on the difference between "now" and the nearest interval (05, 20, 35 or 50 minutes past the hour). – Daniel Kelley Sep 09 '14 at 16:04

1 Answers1

1

The idea is to have a timer and Enable it when you want to set the delay in your program:

System.Timers.Timer Delay = new System.Timers.Timer();
Delay.Elapsed += new System.Timers.ElapsedEventHandler(Delay_Elapsed);
Delay.Interval=Convert.ToInt32(milliseconds);
Delay.Enabled = false;

 void Delay_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  {
    Delay.Enabled = false; 
  }
......
.....
if (nextTimeRead > now) //Yes, so wait 7 minutes for files to be available
    {
        TimeSpan span = nextTimeRead.Subtract(now);
        Double milliseconds = span.TotalMilliseconds;
        Console.WriteLine("Sleep for milliseconds: " + milliseconds.ToString());
        Delay.Enabled = true;
        while (Delay.Enabled)
        {
          ////Wait until time passes
        }
        Console.WriteLine("Download files after sleep of: " + nextTimeRead.ToString());
        DownloadFilesByPeriod(nextTimeRead);
    }
apomene
  • 14,282
  • 9
  • 46
  • 72
  • 1
    +1. Side note: it may not solve "it's not working properly in the server" assuming "server" means "ASP.Net application" as ASP.Net may decide to recycle AppPool before timer triggers (also issue is the same with `Sleep` and `Task.Delay`)... – Alexei Levenkov Sep 09 '14 at 14:31
  • Sorry for not being more detailed with that. The only thing I can say about that is that the server hits `Thread.Sleep(101270)` (about 1.66 minutes) and never moves forward after that. – Joe_Hendricks Sep 09 '14 at 14:35