Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建一个扩展方法来执行定期工作_C#_Extension Methods_Async Await_C# 5.0 - Fatal编程技术网

C# 创建一个扩展方法来执行定期工作

C# 创建一个扩展方法来执行定期工作,c#,extension-methods,async-await,c#-5.0,C#,Extension Methods,Async Await,C# 5.0,我在这里找到了一种使用异步/等待模式进行定期工作的好方法: 现在我想做的是创建一个扩展方法,以便 someInstruction.DoPeriodic(TimeSpan.FromSeconds(5)); 这可能吗?如果可能,你会怎么做 编辑: 到目前为止,我将上述URL中的代码重构为一个扩展方法,但我不知道如何继续 public static class ExtensionMethods { public static async Task<T> DoPeriodic&

我在这里找到了一种使用异步/等待模式进行定期工作的好方法:

现在我想做的是创建一个扩展方法,以便

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);
        }
    }
}
公共静态类扩展方法{
公共静态异步任务DoPeriodic(此任务任务、CancellationToken令牌、TimeSpan dueTime、TimeSpan间隔){
//开始周期循环之前的初始等待时间。
如果(dueTime>TimeSpan.Zero)
等待任务。延迟(dueTime,令牌);
//重复此循环直到取消。
而(!token.IsCancellationRequested){
//等待再次重复。
如果(间隔>时间跨度0)
等待任务。延迟(间隔、令牌);
}
}
}
定期工作代码是否访问任何
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
    }
}
当然,您必须将
someInstruction
作为参数传递给
任务
构造函数(有一个构造函数重载允许您这样做)

根据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
}
然后你就这样使用它:

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

您知道如何创建扩展方法吗?如果是,你有答案;如果不是,你可以使用谷歌。@MarcinJuraszek我已经将链接中的代码重构为一个扩展方法,但我不知道如何继续。看我的编辑。我的意图是这样的:我在所有地方重复使用该代码,只有带有“//TODO:在这里做一些工作”注释的行。所以我想,与其到处复制和粘贴代码,我希望有一些样板代码,只需传递说明。这就是扩展方法的想法。谢谢!!顺便说一句,“公共静态任务DoPeriodicWorkAsync”应该是“公共静态异步任务DoPeriodicWorkAsync”;)非常有用的答案,但是我在取消它时遇到了一个异常:
TaskCanceledException
CancellationTokenSource.token
上使用
Cancel()方法后,我传递给该方法。如何正确处理取消
周期运行程序
?谢谢