异步等待不使用Timer

时间:2017-09-16 11:47:21

标签: c# asynchronous async-await

我有一个Presence监控类,用于检测用户的活动/非活动状态。该类在其Start方法中有一个计时器,它调用了应用程序启动:

public class PresenceMonitor
{
    private volatile bool _running;
    private Timer _timer;
    private readonly TimeSpan _presenceCheckInterval = TimeSpan.FromMinutes(1);


    public PresenceMonitor()
    {
    }

    public void Start()
    {
        // Start the timer
        _timer = new Timer(_ =>
        {
            Check();
        }, null, TimeSpan.Zero, _presenceCheckInterval);
    }

    private void Check()
    {
        if (_running)
        {
            return;
        }

        _running = true;

        // Dowork
    }
}

每隔一分钟就会触发“检查”方法。这段代码工作正常,但现在我的“Do work”方法变得异常等待,所以我不得不将这个Presence Monitor类更改为这样的东西:

public class PresenceMonitor
{
    private volatile bool _running;
    private Timer _timer;
    private readonly TimeSpan _presenceCheckInterval = TimeSpan.FromMinutes(1);


    public PresenceMonitor()
    {
    }

    public void Start()
    {
        // Start the timer
        var timer = new System.Threading.Timer(async (e) =>
        {
            await CheckAsync();
        }, null, TimeSpan.Zero, _presenceCheckInterval);
    }

    private async Task CheckAsync()
    {
        if (_running)
        {
            return;
        }

        _running = true;

        // await DoworkAsync
    }
} 

不幸的是,“CheckAsync”方法现在只被触发一次而不是每分钟。你能告诉我在这里做错了什么,经常间隔后调用异步等待吗?

有没有正确的方法来做同样的事情?

2 个答案:

答案 0 :(得分:3)

你可以考虑创建一个事件和处理程序来处理计时器滴答,然后调用你的支票。

if (! pw.equals(pwEnter) ) {

答案 1 :(得分:0)

如果我理解你的要求,你可以摆脱计时器并使用异步循环 但是你也需要使Start方法异步

public class PresenceMonitor
{
    private volatile bool _running; // possible not needed "volatile" anymore
    private readonly int _presenceCheckInterval = 60000; // Milliseconds

    public PresenceMonitor()
    {
    }

    public async Task Start()
    {
        while (true) // may be use some "exit" logic
        {
           await CheckAsync();
           await Task.Delay(_presenceCheckInterval) 
        }
    }

    private async Task CheckAsync()
    {
        if (_running)
        {
            return;
        }

        _running = true;

        // await DoworkAsync
    }
} 

然后你可以开始监控

var monitor = new PresenceMonitor();
await monitor.Start();

您甚至可以以同步方式开始监控

var monitor = new PresenceMonitor();
monitor.Start(); // Will start monitoring

但上面的方法是危险的"顺便说一下,CheckAsync方法中抛出的任何异常都不会传播。当您开始使用async-await时,请准备好"转换"整个申请来支持它。