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

本文关键字:Task Delay 事件 | 更新日期: 2023-09-27 18:18:43

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

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

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

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

您不能"重置"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从一个事件"创建"一个任务)。如果延迟任务先完成,则触发代码。

下面是一个例子:

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