2017-09-01 79 views
1

起初我认为这只是一个“How to wait for async method to complete?”问题。但是,我认为这不仅仅是一点。防止计时器重新启动,直到完成异步任务

我有一个计时器设置为这样......

public void Start() 
{ 
    _timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); 
    _timer.Interval = _context.adpSettings.SyncInterval * 1000; 
    _timer.AutoReset = false; 
    _timer.Enabled = true; 
} 

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
{ 
    var t = ExecuteTransactionReportAsync(); 
    _timer.Start(); 
} 

private async Task ExecuteTransactionReportAsync() 
{ 
    AccessEvent accessEvent = new AccessEvent(); 
    .... do some logic 
    await _context.GetConnector().EnqeueuEventAsync(accessEvent); 
} 

我试图做的是没有再timer_Elapsed()火,直到ExecuteTransactionReportAsync()完成后。但是,因为ExecuteTransactionReportAsync()是异步的,所以进程继续进行,并且timer_Elapsed()将再次触发。

在现实生活中,它不会花费ExecuteTransactionReportAsync()超过10秒才能完成任务。 (至少不是或者我们有其他问题。)但是当我调试时,这是一个痛苦。

有没有一个简单的解决方案,不涉及使ExecuteTransactionReportAsync()非异步?

+1

停止计时,运行异步任务,加上'ContinueWith '重启计时器的任务? – DavidG

+1

不要使用定时器,而应该在循环结束时使用带有延迟循环的单线程。 – Sinatr

+1

'var t = await ExecuteTransactionReportAsync();'?你必须使eventHandler async来使用它。 – Fildor

回答

1

如果我的TAP的理解是正确的,那么这应该工作打算:

private async void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
{ 
    await ExecuteTransactionReportAsync(); 
    _timer.Start(); 
} 

还是什么DavidG是在暗示:

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
{ 
    _timer.Stop(); 
    ExecuteTransactionReportAsync().ContinueWith(() => {_timer.Start(); }); 
} 
+0

这很有效!我以为我试过这个,但我猜不是。谢谢! –

+0

好吧,在我第一次评论时,当我说“那有用”时,我正在谈论你的第一个例子。你的第二个例子更多的是我最初的想法或寻找的东西。但我更喜欢你的第一个例子。 –