2017-09-22 3 views
0

들어오는 파일에 대한 파일 시스템을보기 위해 FileSystemWatcher을 회전시키는 프로세스가 있습니다.지연된 작업에 시간을 어떻게 추가합니까?

취소 토큰이 설정되거나 시간이 만료 된 후 (예 : 10 분) FSW를 취소하는 지연을 Task.Delay으로 설정합니다.

하지만 새로운 파일이 나타날 때마다 추가 지연을 추가 할 수 있도록 구성하고 싶습니다. 그래서 일종의 슬라이딩 만료 지연.

+3

취소 및 다시

그런 단순한 방법으로 FileSystemWatcher의 "지연 처분"을 만들 수 있습니까? – Default

+0

처음에는 내 생각 이었지만 가능한 경우 FSW를 계속 실행하고 싶습니다. 몇 초 (또는 그 이하)마다 파일이 수신 될 수 있고 이로 인해 많은 취소와 레크리에이션이 생길 수 있기 때문입니다. 필자가 근본적으로 성취하고자하는 것은 FSW가 첫 번째 파일부터 시작하여 마지막 파일이 10 분이 될 때까지 실행하는 것입니다. – mare

+0

아니요, 죄송합니다. _ 실행 작업을 취소하고 다시 만드십시오. 그래서'restartTimeoutCancellation' 취소 .. 이해할 수있는 문장으로 공식화 할 수 있는지 보도록하겠습니다. – Default

답변

2

지연 시간을 약간 변경하여 실행 시간을 변경할 수 있습니다.

작은 예제를 만들었습니다.

CancellationTokenSource cts = new CancellationTokenSource(); 
await watcher.DisposeDelayed(TimeSpan.FromSeconds(10), cts.Token); 

내가 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(); 
     } 
    } 
} 
+0

나는이 코드로 갈 두 번째 생각을 갖고있다. 다소 복잡해 보인다. – mare

관련 문제