0

我需要实现一个定期计时器(10 秒),它将检查一些更改并更新数据库和 UI。我需要等到“作业”完成,然后再次启动计时器。我打电话

timer.Cancel()

在“作业”开始,然后在完成时再次创建计时器。但似乎当我使用使用 async 关键字的工作项处理程序时,线程池工作项可能会在处理程序中的所有代码执行之前设置为完整状态。查看完整代码:

    private bool IsStop = false;

    private async Task  DoWork()
    {
        try
        {
            if (IsStop)
            {
                Stop();
                return;
            }
            timer.Cancel();
            var resultIds = await DB.getUnresolvedData();

            if (resultIds.IsNullOrEmpty())
            {
                return;
            }
            var json = await server.RequestSTatus(resultIds);

            if (string.IsNullOrEmpty(json))
                return;
            Model result = JsonConvert.DeserializeObject<Model>(json);
            UpdateDB(result);
        }

        catch (Exception ex)
        {

        }

        finally
        {
            Start();
        }
    }

    public void Start()
    {
        if (IsStop) return;

        timer = ThreadPoolTimer.CreatePeriodicTimer(async (t) =>
        {
            await DoWork();
        }, TimeSpan.FromSeconds(10));
    }

问题是,我怎样才能等到“工作”完成后再重新开始?

4

1 回答 1

1

你可以做得有点不同。但代码会更清晰,无论如何你都会使用 ThreadPool。只需将 Task.Delay 用于计时器。像这样的东西。

    private bool isRunning;

    public async void Start()
    {
        if (isRunning)
            return;

        isRunning = true;
        while (isRunning)
        {
            await DoWork();
            //wait period.
            await Task.Delay(TimeSpan.FromSeconds(10));
            if (!isRunning)
                return;
        }
    }

    private async Task DoWork()
    {
        //Do your work here.
    }

    public void Stop()
    {
        isRunning = false;
    }

这只是一个普遍的想法。

于 2017-03-21T16:38:42.050 回答