事件触发后如何重设Task.Delay()? [英] How to reset a Task.Delay() after a event fired?
问题描述
我试图让FileSystemWatcher超过5分钟未收到任何更改后触发一些代码.
I am trying to let some code fire after my FileSystemWatcher hasn't received any changes for more then 5 minutes.
我当前的方法是在更改后调用 await Task.Delay();
,希望届时用户已完成.显然,这不是不是的方法.
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.
所以我的问题是:事件触发后如何重置Task.Delay()?
So my question: How to reset a Task.Delay() after a event fired?
推荐答案
您不能重置" Task.Delay
,但是您可以重置计时器,这使其成为解决问题的理想之选这个问题.
You can't "reset" a Task.Delay
, but you can reset a timer which makes it an ideal candidate to solve this problem.
这是一个例子:
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
从事件中创建"任务).如果延迟任务首先完成,请触发您的代码.
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.
这是一个例子:
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>();
}
这篇关于事件触发后如何重设Task.Delay()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!