2017-10-13 54 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在範圍內