2013-04-12 15 views
5

Mam usługa Windows i pisałem kod aby uruchomić zadanie w OnStart() imprezy:Jak uruchomić zadanie po uruchomieniu usługi systemu Windows?

protected override void OnStart(string[] args) 
     { 
      this.DoTask(); 
     } 

private void DoTask() 
     { 
      Task task1 = Task.Factory.StartNew(() => this.OriginalFileProcessor.StartPolling()); 

      try 
      { 
       Task.Wait(task1); 
      } 
      catch (Exception ex) 
      { 
       this.Log.Error("Failed running the task", ex); 
      }   
     } 

DoTask to niekończąca się pętla. Zatrzyma się tylko wtedy, gdy usługa zostanie zatrzymana.

Ale gdy próbuję uruchomić usługę, to czeka długo potem daje mi poniższy błąd:

Windows could not start the ... service on Local Computer. 
Error 1053: The service did not respond to the start or control request in a timely fashion. 

Jak go rozwiązać?

Odpowiedz

7

Dlaczego czekasz na zakończenie swojego zadania?

Myślę, że Task.Wait blokuje bieżący wątek, a następnie masz limit czasu podczas uruchamiania usługi.

EDIT: Trzeba usunąć ten blok:

try 
{ 
    Task.Wait(task1); 
} 
catch (Exception ex) 
{ 
    this.Log.Error("Failed running the task", ex); 
} 

Task.Wait rzeczywiście blokuje bieżącego wątku. Według MSDN:

Task.Wait Method

Waits for the Task to complete execution.

EDIT 2 Czy to zamiast

Task task1 = Task.Factory.StartNew(() => this.OriginalFileProcessor.StartPolling()).ContinueWith(t => 
{ 
    var aggException = t.Exception.Flatten(); 
    foreach(var ex in aggException.InnerExceptions) 
     this.Log.Error("Failed running the task", ex); 
}, 
TaskContinuationOptions.OnlyOnFaulted); 
+0

Czekanie nie czeka jako takie. Chodzi mi o to, że po prostu uchwyci wszelkie wyjątki od tego zadania. –

+0

Czekanie * oznacza * "oczekiwanie jako takie". Twój kod siedzi tam, nic nie robiąc, czekając na zakończenie tego zadania. I robi to czekać na ten sam wątek, który nazwał 'OnStart'. –

+0

nie. służy do przechwytywania wyjątku. –

1

W pętli należy sprawdzić, czy stan usługi "zatrzymuje się" i wyjść z pętli. Masz 5 sekund na zrobienie tego, zanim OS zdecyduje cię zabić.

1

myślę, że to jest, bo czekają na OriginalFileProcessor.StartPolling() do końca, ale to nigdy nie zdarza. Powinieneś przenieść instancję zadania do osobnego członka i nie czekać na jego zakończenie:

private Task m_task = null; 

private void DoTask() 
{ 
    try 
    { 
     m_task = Task.Factory.StartNew(() => this.StartPolling()); 
    } 
    catch 
    { 
     this.Log.Error("Unable to start task", ex); 
     throw; // Rethrow, so that the OS knows, there was something wrong. 
    }   
} 

private void StartPolling() 
{ 
    try 
    { 
     this.OriginalFileProcessor.StartPolling(); 
    } 
    catch (Exception ex) 
    { 
     this.Log.Error("Failed running the task", ex); 
    } 
} 
+0

Twój haczyk nigdy się nie złapie. Można go złapać tylko wtedy, gdy na niego czekasz. –

+0

@TheLight: Powinien wychwytywać wyjątki tylko z ['Task.Factory.StartNew'] (http://msdn.microsoft.com/en-us/library/dd321439.aspx), a nie z' StartPolling'. Zaczynasz uruchamiać usługę asynchroniczną, a nie czekać na jej zakończenie. Zaktualizowano odpowiedź. – Carsten

+0

Task.Factory.StartNew nie zwraca wyjątku. Możesz przechwycić wyjątek podczas oczekiwania na zadanie. czy jest jakiś inny sposób? –

Powiązane problemy