问题
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