2017-10-13 27 views
1

我正在尝试改进一些代码,并希望创建运行异步的定时器的更一般的实现。在下面的情况下,MethodA按预期工作并每4秒写入一次控制台。我希望MethodB也能工作,但不知何故它只执行一次。当任务作为参数传递时Timer不工作

public async Task InitTimers() 
{ 
    MethodA(TimeSpan.FromSeconds(4)); 
    MethodB(TimeSpan.FromSeconds(4), ExecTimer()); 
} 

private async Task MethodA(TimeSpan refreshTime) 
{ 
    var aTimer = new Timer(); 
    aTimer.Elapsed += (s, e) => ExecTimer().ConfigureAwait(false); 
    aTimer.Interval = refreshTime.TotalMilliseconds; 
    aTimer.Enabled = true; 

    // Immediately trigger first time 
    ExecTimer().ConfigureAwait(false); 
} 

private async Task MethodB(TimeSpan refreshTime, Task task) 
{ 
    var aTimer = new Timer(); 
    aTimer.Elapsed += (s, e) => task.ConfigureAwait(false); 
    aTimer.Interval = refreshTime.TotalMilliseconds; 
    aTimer.Enabled = true; 

    // Immediately trigger first time 
    task.ConfigureAwait(false); 
} 

private async Task ExecTimer() 
{ 
    Console.WriteLine("Hello World!"); 
} 

任何想法是什么导致MethodB只运行一次?

+0

为什么不使用Task.Delay?无论如何,定时器必须存在才能定期执行任何事情。一旦退出上下文,变量的内容就会被丢弃。而不是使用字段 –

+0

此外,您无法“重新执行”任务。您不要通过等待它或者调用'ConfigureAwait'来执行它。这个任务是一个*承诺*,一个已经开始的操作将在未来完成。 ExecTimer已经完成了,当它返回已经完成的任务时。在这两种情况下,定时器都不会做任何事情。 –

+0

您能否进一步解释“创建运行异步的定时器的通用实现”以及您实际尝试实现的内容? – Enigmativity

回答

2

一旦方法MethodA/MethodB完成,您的Timer即使在超出范围时也会被丢弃。您需要在Task之外创建它们,否则请保持Task运行,Timer在范围内