0

I tried to generalize the delayed action call proposed in Delayed function calls To use it for scheduling tasks that I need executed in the next 24h, but it does not work. I don't understand why the direct call proposed there works while my generalized one does not do anything.

    public void RunScheduledTasks()
    {
        //This generic way fails
        RunScheduledMethod(bar1, new TimeSpan(15, 31, 30)); //DOES NOTHING

        //This way works
        TimeSpan Time1 = new TimeSpan(15, 31, 30); 
        if (Time1 > DateTime.Now.TimeOfDay)
        {
            Time1 -= DateTime.Now.TimeOfDay;
            Task.Delay(Time1).ContinueWith(t => bar1()); //WORKS OK.
        }

    }
    public void RunScheduledMethod(Action methodToRun, TimeSpan TimeToRun)
    {
        TimeToRun -= DateTime.Now.TimeOfDay;
        Task.Delay(TimeToRun).ContinueWith(t => methodToRun);
    }
    public void bar1()
    {
        MessageBox.Show("Bar1 called" + DateTime.Now.TimeOfDay);
    }
Guy
  • 1,232
  • 10
  • 21
  • 1
    First tought (might not work): Try changing `ContinueWith(t => methodToRun)` to `ContinueWith(t => methodToRun())` – Chrᴉz remembers Monica Aug 27 '19 at 12:51
  • Yes. You did it. Shall I add the answer or you will? (need to add the date validation inside as well). – Guy Aug 27 '19 at 12:55
  • just close/delete the question, it was just a typo :). no need for this question to stay here. – Chrᴉz remembers Monica Aug 27 '19 at 13:01
  • I looked for such code and couldn't find a working one. For me a typo results in compile error. I guess delegates make it more sensitive. I even tried methodToRun.Method and it didn't work :-). – Guy Aug 27 '19 at 13:05
  • Unfortunately, if I want to call an async Task instead of a plain method, I have to create anoteher method to facilitate this: `public async Task RunScheduledMethods(Func methodToRun, TimeSpan timeToRun)` a bit ugly. – Guy Aug 27 '19 at 14:39

1 Answers1

0

Thanks to the proposal by Crhiz: adding () to the methodname, it works. Here is the full method with safeguards against time which is too early:

public void RunScheduledMethod(Action methodToRun, TimeSpan timeToRun)
    {
        if (timeToRun <= DateTime.Now.TimeOfDay)
            timeToRun = timeToRun + new TimeSpan(1, 0, 0, 0);
        timeToRun -= DateTime.Now.TimeOfDay;
        Task.Delay(timeToRun).ContinueWith(t => methodToRun());
    }

To call it just do as shown in the question, or below:

RunScheduledMethod(bar2, new TimeSpan(15, 59, 00));
Guy
  • 1,232
  • 10
  • 21