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

时间:2018-08-15 10:09:09

标签: c# .net

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

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

似乎您无法等待分配给它的功能。有没有解决的办法?我已经多次搜索了这个问题,但是所有出现的都是与非同步解决方案无关的SO帖子。

3 个答案:

答案 0 :(得分:0)

在此用例中,您实际上不需要计时器。这是在控制台程序中每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);
    }

}

答案 1 :(得分:0)

如果您希望每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
}

答案 2 :(得分:0)

我建议使用Microsoft的Reactive Framework(NuGet“ System.Reactive”并添加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()即可停止间隔计时器。很简单。