为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
素胚勾勒不出你 2021-11-28 19:48:24
所以我正在使用线程计时器并希望每 10 秒运行一次任务。在这个异步任务方法中,我在其中运行其他任务。我尝试使用 System.Threading.Timer 执行此操作。_taskTimer = new Timer(statusChecker.CheckStatus, autoEvent, 1000, 250);似乎您不能等待分配给它的功能。有解决办法吗?我已经多次用谷歌搜索这个问题,但所有出现的都是关于非异步解决方案的无关紧要的帖子。
查看完整描述

3 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

对于此用例,您实际上并不需要计时器。这是每 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);

    }


}


查看完整回答
反对 回复 2021-11-28
?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

如果您想每 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

}


查看完整回答
反对 回复 2021-11-28
?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

我建议使用 Microsoft 的 Reactive Framework (NuGet "System.Reactive" and add using System.Reactive.Linq;),然后你可以这样做:


IObservable<bool> query =

    from n in Observable.Interval(TimeSpan.FromSeconds(10.0))

    from s in Observable.FromAsync(() => statusChecker.CheckStatus())

    select s;


IDisposable subscription =

    query.Subscribe(status =>

    {

        /* Do something with each `status` as it arrives */

    });

这假设.CheckStatus()返回Task<bool>.


这一切都是通过后台线程完成的,并且是异步的。只需调用subscription.Dispose()停止间隔计时器。简单的。


查看完整回答
反对 回复 2021-11-28
  • 3 回答
  • 0 关注
  • 258 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信