定期以指定的时间间隔运行异步方法
我需要从C#Web应用程序向服务发布一些数据。 用户使用应用程序时收集数据本身(一种使用统计信息)。 我不希望在每个用户的请求期间向服务发送数据,我宁愿在应用程序中收集数据,然后在一个单独的线程中发送单个请求中的所有数据,这不会满足用户的请求(我的意思是用户不必等待服务处理请求)。 为此,我需要一种JS的setInterval
模拟 – 每隔X秒启动一次函数,将所有收集的数据刷新到服务中。
我发现Timer
类提供了一些类似的( Elapsed
事件)。 但是,这允许只运行一次方法,但这不是一个大问题。 它的主要困难是需要签名
void MethodName(object e, ElapsedEventArgs args)
虽然我想启动异步方法,它将调用web服务(输入参数并不重要):
async Task MethodName(object e, ElapsedEventArgs args)
任何人都可以建议如何解决所描述的任务? 任何提示赞赏。
async
等价物是一个带有Task.Delay
的while
循环(内部使用System.Threading.Timer
):
public async Task PeriodicFooAsync(TimeSpan interval, CancellationToken cancellationToken) { while (true) { await FooAsync(); await Task.Delay(interval, cancellationToken) } }
传递CancellationToken
非常重要,这样您就可以在需要时停止该操作(例如,当您关闭应用程序时)。
现在,虽然这通常与.Net相关,但在ASP.Net中,做任何类型的火灾都会很危险。 有几个解决方案(如HangFire),其中一些记录在Spark 和Forget on ASP.NET上由Stephen Cleary在其他人如何在ASP.NET中运行后台任务由Scott Hanselman
这样做的简单方法是使用Tasks和一个简单的循环:
public async Task StartTimer(CancellationToken cancellationToken) { await Task.Run(async () => { while (true) { DoSomething(); await Task.Delay(10000, cancellationToken); if (cancellationToken.IsCancellationRequested) break; } }); }
当你想要停止线程时,只需中止令牌:
cancellationToken.Cancel();