lig*_*txx 5 c# extension-methods async-await c#-5.0
我找到了一个如何使用async/await模式定期工作的好方法:https://stackoverflow.com/a/14297203/899260
现在我想做的是创建一个扩展方法,以便我可以做到
someInstruction.DoPeriodic(TimeSpan.FromSeconds(5));
Run Code Online (Sandbox Code Playgroud)
这有可能吗,如果,你会怎么做?
编辑:
到目前为止,我将上面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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
“定期工作”代码是否访问任何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
}
}
Run Code Online (Sandbox Code Playgroud)
当然,您必须作为参数传递someInstruction
给Task
构造函数(有一个构造函数重载允许您执行此操作)。
根据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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后你像这样使用它:
PeriodicRunner.DoPeriodicWorkAsync(MethodToRun, dueTime, interval, token);
void MethodToRun()
{
//Code to run goes here
}
Run Code Online (Sandbox Code Playgroud)
或者使用简单的 lambda 表达式:
PeriodicRunner.DoPeriodicWorkAsync(() => { /*Put the code to run here */},
dueTime, interval, token);
Run Code Online (Sandbox Code Playgroud)