猿问

是否可以使用 System.Threading.Timer 运行异步任务?

所以我正在使用线程计时器并希望每 10 秒运行一次任务。在这个异步任务方法中,我在其中运行其他任务。我尝试使用 System.Threading.Timer 执行此操作。

_taskTimer = new Timer(statusChecker.CheckStatus, autoEvent, 1000, 250);

似乎您不能等待分配给它的功能。有解决办法吗?我已经多次用谷歌搜索这个问题,但所有出现的都是关于非异步解决方案的无关紧要的帖子。


素胚勾勒不出你
浏览 259回答 3
3回答

海绵宝宝撒

对于此用例,您实际上并不需要计时器。这是每 x 秒连续调用一个函数的一种方法(在控制台程序中):class Program{    static Task statusCheckingTask;    static void Main(string[] args)    {        statusCheckingTask = CheckStatusTask(10);        Console.ReadLine();    }    static async Task CheckStatusTask(int delayInSeconds)    {        while (true)        {            await CheckStatus();            await Task.Delay(TimeSpan.FromSeconds(delayInSeconds));        }    }    static async Task CheckStatus()    {        Console.WriteLine("Checking status...");        await Task.FromResult(0);    }}

牧羊人nacy

如果您想每 250 毫秒触发一次状态检查,无论之前的尝试结果如何,请使用以下命令:while (true){    Task.Run(() => statusChecker.CheckStatus(autoEvent));    await Task.Delay(TimeSpan.FromSeconds(250));}如果您只想在上一次尝试完成时触发状态检查,请使用以下命令:while (true){    await statusChecker.CheckStatus(autoEvent);    await Task.Delay(TimeSpan.FromSeconds(250));}两种情况都假设statusChecker.CheckStatus返回一个Task对象,例如:public async Task CheckStatus(object autoEvent){    // some async status checking}

qq_花开花谢_0

我建议使用 Microsoft 的 Reactive Framework (NuGet "System.Reactive" and add using System.Reactive.Linq;),然后你可以这样做:IObservable<bool> query =&nbsp; &nbsp; from n in Observable.Interval(TimeSpan.FromSeconds(10.0))&nbsp; &nbsp; from s in Observable.FromAsync(() => statusChecker.CheckStatus())&nbsp; &nbsp; select s;IDisposable subscription =&nbsp; &nbsp; query.Subscribe(status =>&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; /* Do something with each `status` as it arrives */&nbsp; &nbsp; });这假设.CheckStatus()返回Task<bool>.这一切都是通过后台线程完成的,并且是异步的。只需调用subscription.Dispose()停止间隔计时器。简单的。
随时随地看视频慕课网APP
我要回答