如何在事件触发后重置 Task.Delay()?

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

我试图在我的 FileSystemWatcher 超过 5 分钟未收到任何更改后触发一些代码。

我目前的做法是在更改后调用 await Task.Delay();,希望用户届时完成。这显然是的方法。

所以我的问题是:如何在事件触发后重置 Task.Delay()?

您不能 "reset" Task.Delay,但您可以重置计时器,这使其成为解决此问题的理想选择。

这是一个例子:

    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));
    }

但是你不必使用定时器,你仍然可以使用Task.Delay额外的任务:想法是等待两个任务,延迟和等待文件更改(你可以使用 TaskCompletionSource 到 "create" 事件中的任务)。 如果延迟任务先完成,则触发您的代码。

这是一个例子:

    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>();
    }