5

我在这里找到了一个关于如何使用 async/await 模式进行定期工作的好方法:https ://stackoverflow.com/a/14297203/899260

现在我想做的是创建一个扩展方法,这样我就可以做

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

这有可能吗,如果,你会怎么做?

编辑:

到目前为止,我将上面 URL 中的代码重构为扩展方法,但我不知道如何从那里着手

  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);
        }
    }
}
4

1 回答 1

4

“定期工作”代码是否访问任何someInstruction公共成员?如果不是,那么首先使用扩展方法没有多大意义。

如果是这样,并假设它someInstruction是 的一个实例SomeClass,您可以执行以下操作:

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

当然,您必须将其作为参数传递someInstructionTask构造函数(有一个构造函数重载允许您这样做)。

根据 OP 的评论更新:

如果你只是想有一个可重用的方法来定期执行任意代码,那么扩展方法不是你需要的,而是一个简单的实用程序类。从您提供的链接中调整代码,它将是这样的:

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);       
  }
}
}

然后你像这样使用它:

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

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

或使用简单的 lambda 表达式:

PeriodicRunner.DoPeriodicWorkAsync(() => { /*Put the code to run here */},
   dueTime, interval, token);
于 2013-03-18T07:53:40.190 回答