我有一个进程,我调高FileSystemWatcher
来查看传入文件的文件系统。
我设置Task.Delay
的延迟,在设置取消令牌或时间到期后(例如10分钟)取消FSW。
watcher.EnableRaisingEvents = true;
// start the timer
RunAfterDelay(TimeSpan.FromMinutes(10), cts.Token, () =>
{
// get rid of the watcher
watcher.Dispose();
});
private async void RunAfterDelay(TimeSpan delay, CancellationToken token, Action action)
{
await Task.Delay(delay, token);
if (!token.IsCancellationRequested)
{
action();
}
}
但是我想以一种方式配置它,以便每次出现新文件时都能添加额外的延迟。因此有效地实现了某种滑动到期延迟。
答案 0 :(得分:2)
您可以稍微更改延迟方法,以便能够改变执行时间。
我为你创建了一个小例子。
然后你可以用一种简单的方式对FileSystemWatcher
进行“延迟处理”:
CancellationTokenSource cts = new CancellationTokenSource();
await watcher.DisposeDelayed(TimeSpan.FromSeconds(10), cts.Token);
我为DisposeDelayed
创建了一个扩展方法FileSystemWatcher
:
static class Utilities
{
public static async Task DisposeDelayed(this FileSystemWatcher watcher, TimeSpan inactivePeriod, CancellationToken ct)
{
DateTime disposalTime = DateTime.Now + inactivePeriod;
FileSystemEventHandler postponeTrigger = (s, e) => disposalTime = DateTime.Now + inactivePeriod;
watcher.Created += postponeTrigger;
watcher.Changed += postponeTrigger;
// add here other event handlers you need to postpone the disposal
try
{
await RunAtTimePoint(() => disposalTime, ct, watcher.Dispose).ConfigureAwait(false);
}
finally
{
// don't forget to unsubscribe from each event
watcher.Created -= postponeTrigger;
watcher.Changed -= postponeTrigger;
}
}
// You can also use this method for other tasks if you need
public static async Task RunAtTimePoint(Func<DateTime> execTimeProvider, CancellationToken token, Action action)
{
int delayTime;
do
{
// first, calculate the time left until the execution
DateTime execTime = execTimeProvider();
TimeSpan timeLeft = execTime - DateTime.Now;
// we delay in 1000 ms chunks;
// but if the delay time is less, we need to handle that
delayTime = (int)Math.Min(1000d, timeLeft.TotalMilliseconds);
if (delayTime > 0)
{
// don't forget the ConfigureAwait call:
// we don't need the context switch each time
await Task.Delay(delayTime, token).ConfigureAwait(false);
}
}
while (delayTime > 0 && !token.IsCancellationRequested);
if (!token.IsCancellationRequested)
{
action();
}
}
}