Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create an extension method to do periodic work

I found a great way on how to do periodic work using the async/await pattern over here: https://stackoverflow.com/a/14297203/899260

Now what I'd like to do is to create an extension method so that I can do

someInstruction.DoPeriodic(TimeSpan.FromSeconds(5));

Is that possible at all, and if, how would you do it?

EDIT:

So far, I refactored the code from the URL above into an extension method, but I don't know how to proceed from there

  public static class ExtensionMethods {
    public static async Task<T> DoPeriodic<T>(this Task<T> task, CancellationToken token, TimeSpan dueTime, TimeSpan interval) {
        // Initial wait time before we begin the periodic loop.
        if (dueTime > TimeSpan.Zero)
            await Task.Delay(dueTime, token);

        // Repeat this loop until cancelled.
        while (!token.IsCancellationRequested) {


            // Wait to repeat again.
            if (interval > TimeSpan.Zero)
                await Task.Delay(interval, token);
        }
    }
}
like image 776
lightxx Avatar asked Oct 05 '22 16:10

lightxx


1 Answers

Is the "periodic work" code accessing any of the someInstruction public members? If not, it does not make much sense to use an extension method in the first place.

if it does, and assuming that someInstruction is an instance of SomeClass, you could do something like the following:

public static class SomeClassExtensions
{
    public static async Task DoPeriodicWorkAsync(
                                       this SomeClass someInstruction,
                                       TimeSpan dueTime, 
                                       TimeSpan interval, 
                                       CancellationToken token)
    {
        //Create and return the task here
    }
}

Of course you must pass someInstruction to the Task constructor as a parameter (there is a constructor overload that allows you to do that).

UPDATE based on comment by OP:

If you just want to have a reusable method for executing arbitrary code periodically, then an extension method is not what you need, but rather a simple utility class. Adapting the code from the link you provided, it would be something like this:

public static class PeriodicRunner
{
public static async Task DoPeriodicWorkAsync(
                                Action workToPerform,
                                TimeSpan dueTime, 
                                TimeSpan interval, 
                                CancellationToken token)
{
  // Initial wait time before we begin the periodic loop.
  if(dueTime > TimeSpan.Zero)
    await Task.Delay(dueTime, token);

  // Repeat this loop until cancelled.
  while(!token.IsCancellationRequested)
  {
    workToPerform();

    // Wait to repeat again.
    if(interval > TimeSpan.Zero)
      await Task.Delay(interval, token);       
  }
}
}

Then you use it like this:

PeriodicRunner.DoPeriodicWorkAsync(MethodToRun, dueTime, interval, token);

void MethodToRun()
{
    //Code to run goes here
}

or with a simple lambda expression:

PeriodicRunner.DoPeriodicWorkAsync(() => { /*Put the code to run here */},
   dueTime, interval, token);
like image 102
Konamiman Avatar answered Oct 13 '22 12:10

Konamiman