0

My Question is more about getting to the same destination, but there must be another way. Right now im creating a DateTime and compare that to another DateTime and check, if the time difference I set up might be right. So far so good but I just can't accept that I create a new propertie everytime the loop will get into that code.

Is there any possible way to get to the same destination, but in some kind of more effective way?

I got you guys some example code here:

        private void RunService()
        {
            // Runs as long as the service didn't got a stop call.
            while (!SetStop)
            {
                //Get MinutesToWait
                this.MinutesToWait = 5;

                DateTime CheckRunTime = this.LastRun;
                CheckRunTime.AddMinutes(this.MinutesToWait);

                if (DateTime.Now >= CheckRunTime)
                {
                    // Imagine some good and smart and totally runnable code?
                }
            }
        }
Cataklysim
  • 637
  • 6
  • 21
  • You can use a Timer, https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx – R Quijano Jun 06 '17 at 11:21
  • Have you discovered the `System.Threading.Timer` object? But honestly, I would *strongly* urge you to reconsider. [*"If you're writing a Windows Service that runs a timer, you should re-evaluate your solution."*](https://weblogs.asp.net/jongalloway/428303) A scheduled task would be more appropriate. – Cody Gray - on strike Jun 06 '17 at 11:21
  • @CodyGray thats a very interesting Blogpost. I should consider doing it with a scheduled task... but still, im interested in a solution. – Cataklysim Jun 06 '17 at 11:32

2 Answers2

1

If I understood correctly, what you want to do is execute a piece of code some time after the service starts. If that is the case, then your best bet would be to use a timer.

First off, you have to convert the amount of time you want to wait to milliseconds. For example, 5 minutes equals 300000ms. Then, you have to move the code you want to execute to a separate method. I will name this method RunCode() for the example. Finally, you create your timer like so:

private void RunService()
{
    var timer = new Timer(300000);
    timer.Elapsed += (s, e) => this.RunCode();
    timer.Start();
    Thread.Sleep(Timeout.Infinite);
}

What we are doing here is the following.

  1. Instantiating the timer with an interval of 300000ms
  2. Subscribing to the timer's Elapsed event, which fires when the specified time has passed
  3. Starting the timer
  4. Sleeping our main thread forever. This line is optional. Whether you need it or not depends on the structure of your program. If nothing else happens in your code after you start the timer, the main thread and by extension the whole program will exit. However by sleeping it with an infinite timeout, we can prevent that.

If you're sure that this, delayed execution of code, is what you want, then the solution I have provided should work quite well. However I'm worried this may be an XY problem, meaning this is the solution you have come up with for a different issue which could be solved better. So I have to ask, why exactly do you need this in your service?

stelioslogothetis
  • 9,371
  • 3
  • 28
  • 53
  • Cody Gray already commented that a windows service might not be the best approach. I simply want a scheduled routine because of the code behind and how it works. I check data, compare it to another entity and may write a database entry. That routine doesnt need to be fired everytime the routine before finished, Also, we dont know how big the database entries to check will grow and we want to maybe change the check time to another value. A scheduled task is like this is mandatory for the operations im doing. – Cataklysim Jun 06 '17 at 11:38
  • In Addition: Im using `System.Threading` reference and by going like your code I got marks like, the constructor from the timer cant handle "300000" or doenst know `Elapsed` ... – Cataklysim Jun 06 '17 at 12:17
  • This timer is from the `System.Timers` namespace. The `System.Threading.Timer` class is different. I'd recommend going with the `System.Timers.Timer` since, among other things. the alternative isn't thread safe out of the box. You can find a comprehensive comparison [here](https://web.archive.org/web/20150329101415/https://msdn.microsoft.com/en-us/magazine/cc164015.aspx). – stelioslogothetis Jun 06 '17 at 12:19
  • That claim that `System.Threading.Timer` is not thread-safe is utter nonsense. It doesn't handle synchronization for you, but that much should be obvious. It is your job to write thread-safe code. By a standard that allows you to conclude `System.Threading.Timer` is not thread-safe, `System.Threading.Thread` would not be thread-safe either. [These timer classes are perfectly thread-safe](https://stackoverflow.com/a/19577972/366904). And they are functionally equivalent. In fact, one is implemented in terms of the other. – Cody Gray - on strike Jun 07 '17 at 11:01
0

Use System.Timers

static void Main(string[] args) {

        Timer T = new Timer();
        T.Elapsed += Run;
        T.Interval = 100;
        T.Start();

}
static void Run(object source, ElapsedEventArgs e) {

}
David Lindon
  • 305
  • 2
  • 8
  • Maybe give me some examples how that works? Always expect that the person who is asking wont always now what you are doing here? As example, he may not know that you are subscribing to a custom event. Also give a explanation to your solution. Look at the answer from Sty for example. – Cataklysim Jun 06 '17 at 11:40