2017-09-22 23 views
0

私は、受信ファイルのファイルシステムを見るためにFileSystemWatcherをスピンアップするプロセスを持っています。遅延タスクに時間を追加するにはどうすればよいですか?

キャンセルトークンが設定されているか、時間切れ後(たとえば10分)にFSWをキャンセルする遅延をTask.Delayで設定しました。

しかし、新しいファイルが表示されるたびに追加の遅延を追加できるように設定したいと考えています。スライディング期限切れの遅延のような効果的な。

+3

をキャンセルして再作成

その後、単純な方法でFileSystemWatcherの「遅延処分」をすることができますか? – Default

+0

これは当初考えたことですが、可能な限りFSWを稼働させておきたいのですが、数秒(またはそれ以下)ごとにファイルが到着する可能性があり、これにより多くの取り消しや再作成が発生する可能性があります。私が本質的に達成したいのは、最初のファイルが来てから最後のファイルが10分になるまでFSWを実行させることです。 – 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

関連する問題