2015-10-21 3 views
0

Я пытаюсь запустить некоторый код после того, как FileSystemWatcher не получил никаких изменений более 5 минут.Как сбросить Task.Delay() после запуска события?

Мой текущий подход - позвонить по телефону await Task.Delay(); после изменения, надеясь, что пользователь будет к тому времени. Это, очевидно, не путь.

Итак, мой вопрос: как сбросить Task.Delay() после запуска события?

+5

А простой таймер не вышел из моды еще. –

ответ

0

Вы не можете «сбросить» Task.Delay, но вы можете сбросить таймер, который делает его идеальным кандидатом для решения этой проблемы.

Вот пример:

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 для «создания» задачи из события). Если задача задержки завершается первой, запустите свой код.

Вот пример:

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

Что вызывает бесконечность? И безопасно ли его зацикливать? Я продолжаю получать зависания со следующим кодом, даже если вы делаете endlessLoop, чтобы проверить, закончен ли fireMyCode. – Nonlin

+0

Что вызывает бесконечность? В зависимости от контекста вашего приложения. Например, вы можете вызвать его, нажав кнопку (пример Windows Form: private async void button1_Click (отправитель объекта, EventArgs e) { await endlessLoop(); }), безопасно ли его закодировать? Вы имеете в виду вызов функции endlessLoop из цикла? Если это вопрос, то нет, вы не хотели бы этого делать, он предназначен для запуска только один раз, поскольку он запускает бесконечный цикл. – tzachs

+0

Наверное, я в замешательстве, почему вы его зацикливаете? ЕСЛИ вы не зацикливаете его, то Delay не будет продолжаться? По какой-то причине этот код зависает мое приложение. Что начинает тайм-аут? Как тайм-аут может закончиться и, следовательно, равняться любой из готовых задач? Почему бы не вызвать handleFilesNotChanged, почему это делается через цикл? – Nonlin

Смежные вопросы