How to reset a Task.Delay() after a event fired?

笑着哭i 提交于 2021-02-18 18:55:46

问题


I am trying to let some code fire after my FileSystemWatcher hasn't received any changes for more then 5 minutes.

My current approach is to call a await Task.Delay(); after a change, hoping the user is done by then. This obviously is not the way to go.

So my question: How to reset a Task.Delay() after a event fired?


回答1:


You can't "reset" a Task.Delay, but you can reset a timer which makes it an ideal candidate to solve this problem.

Here's an example:

    private System.Threading.Timer timer;

    public void Start()
    {
        timer = new System.Threading.Timer(_ => fireMyCode());
        restartTimer();
    }

    private void onFileChanged(object sender, EventArgs e)
    {
        restartTimer();
    }

    private void restartTimer()
    {
        timer.Change(TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
    }

But you don't have to use timers, you can still use Task.Delay with an additional task: the idea is to wait on two tasks, the delay and waiting for the files to change (you can use TaskCompletionSource to "create" a task from an event). If the delay task completes first, fire your code.

Here's an example:

    TaskCompletionSource<object> fileChanged = new TaskCompletionSource<object>();

    private void onFileChanged(object sender, EventArgs e)
    {
        fileChanged.TrySetResult(null);
    }

    private async Task endlessLoop()
    {
        while (true)
        {
            await handleFilesNotChanged();
        }
    }

    private async Task handleFilesNotChanged()
    {
        Task timeout = Task.Delay(TimeSpan.FromMinutes(5));
        Task waitForFile = fileChanged.Task;

        if (await Task.WhenAny(timeout, waitForFile) == timeout)
        {
            fireMyCode();
        }
        fileChanged = new TaskCompletionSource<object>();
    }


来源:https://stackoverflow.com/questions/33259647/how-to-reset-a-task-delay-after-a-event-fired

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!