2010-08-31 14 views
17

jak przerwać wykonywanie kodu w wątku, jeśli trwa to długo. Mam kilka wątków, które pracują cały czas, ale po chwili kod w wątku jest wykonywany zbyt długo i aplikacja przestaje odpowiadać.przerwij wykonywanie kodu w wątku po 30s

jest to możliwe, że jeśli kod nie zostanie wykonany w ciągu 30 s wątek przestanie go wykonywać i przejdzie do następnego kodu ... więc aplikacja będzie nadal działać i nie przestanie odpowiadać. używam C# .net 3.5

Odpowiedz

19

Moja odpowiedź tutaj jest podobna do tej, którą opublikowałem here.

Można to zrobić, czekając na wątek roboczy z wątku monitorowania przez określony czas, a następnie zdecydowanie zabijając wątek roboczy, jeśli jeszcze nie został ukończony. Zobacz przykładowy kod poniżej.

Generalnie jednak zabijanie wątku z użyciem Thread.Abort nie jest dobrym pomysłem, ponieważ docelowy wątek niekoniecznie znajduje się w znanym stanie i może mieć otwarte uchwyty dla zasobów, które mogą nie zostać zwolnione. Używanie Thread.Abort jest .

Sprytniejszym sposobem jest zmiana wątku roboczego w celu zarządzania własnym życiem. Wątek roboczy może sprawdzić, ile czasu wykonał w dobrze znanych punktach kontrolnych, a następnie przestać, jeśli przekroczył pewien limit. Takie podejście ma tę wadę, że wymaga potencjalnie wielu punktów kontrolnych rozproszonych w trakcie rzeczywistej pracy wykonywanej przez wątek. Ponadto wątek roboczy może z łatwością przekroczyć limit, wykonując zbyt wiele obliczeń między punktami kontrolnymi.

class Program 
{ 
    static void Main(string[] args) 
    { 
     if (RunWithTimeout(LongRunningOperation, TimeSpan.FromMilliseconds(3000))) 
     { 
      Console.WriteLine("Worker thread finished."); 
     } 
     else 
     { 
      Console.WriteLine("Worker thread was aborted."); 
     } 
    } 

    static bool RunWithTimeout(ThreadStart threadStart, TimeSpan timeout) 
    { 
     Thread workerThread = new Thread(threadStart); 

     workerThread.Start(); 

     bool finished = workerThread.Join(timeout); 
     if (!finished) 
      workerThread.Abort(); 

     return finished; 
    } 

    static void LongRunningOperation() 
    { 
     Thread.Sleep(5000); 
    } 
} 
Powiązane problemy