2010-12-15 19 views
7

Esta es una situación difícil de explicar. Disponga de un proceso de servicio que comience con 2 hilos, cada uno de ellos se repite para siempre, pero duerme durante 5 minutos cada vez que finaliza la carga útil.El proceso finaliza debido a StackOverflowException

El problema es que mi segundo hilo termina mucho antes de que la carga útil esté terminada, sin ningún motivo aparente, y tampoco puedo detectar la excepción, ya que parece activarse desde fuera del proceso de delegado.

¿Alguna sugerencia sobre cómo encontrar el problema?

El código ....

public void StartService() 
{ 
    ThreadStart stRecieve = new ThreadStart(DownloadNewMail); 
    ThreadStart stSend = new ThreadStart(SendNewMail); 
    senderThread = new Thread(stRecieve); 
    recieverThread = new Thread(stSend); 

    sendStarted = true; 
    recieveStarted = true; 

    senderThread.Start(); 
    recieverThread.Start(); 
} 

private void DownloadNewMail() 
{ 
    while(recieveStarted) 
    { 
    //Payload.... 

    if (recieveStarted) 
    { 
     Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0)); 
    } 
    } 
} 

private void SendNewMail() 
{ 
    while(sendStarted) 
    { 
    //Payload.... 

    if (sendStarted) 
    { 
     Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0)); 
    } 
    } 

}

+6

Una 'StackOverflowException' a menudo es causada por una recurrencia demasiado profunda o por instancias circulares. ¿Estás utilizando la recursividad en cualquier lugar? – LukeH

+5

"cada hilo bucles para siempre" <- publique ese código aquí –

+0

HA logrado resolverlo creando los hilos como estáticos ... –

Respuesta

4

Do ¿utilizas cualquier biblioteca pesada para tareas como DownloadNewMail y SendNewMail? Por ejemplo, encontré StackOverflows cuando ejecuté trabajos grandes usando Microsoft.SqlServer.Dts.Runtime.Package. Intente ejecutar la misma carga de trabajo secuencialmente dentro de una aplicación de línea de comandos para ver si el problema persiste.

+0

Como se sugirió, la carga útil parece ser muy pesada para una cosa sencilla de enhebrar. Estoy viendo trabajos de Quatz en su lugar ... Aunque parece que hay un problema al usarlo en .NET 4.0 –

6

Si usted está teniendo problemas para seguir el flujo de la ejecución del código de la aplicación, intente ingresar la entrada de métodos con una marca de tiempo y ThreadID.

Además, no puede detectar la excepción porque es una StackOverflowException.

Consulte msdn: "Comenzando con .NET Framework versión 2.0, un objeto de prueba-captura no puede ser capturado por un bloque try-catch y el proceso correspondiente finaliza por defecto. En consecuencia, se aconseja a los usuarios escribir su código para detectar y prevenir un desbordamiento de pila Por ejemplo, si su aplicación depende de la recursividad, utilice un mostrador o una condición de estado para terminar el bucle recursivo "

+4

Recuerdo haber visto esa publicación en MSDN y pensar "wow ... ¿la gente estaba atrapando StackOverflowExceptions para salir de los bucles recursivos?" –

8

intenta comprobar longitud de pila de llamadas en el código:..

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      Hop(); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("Exception - {0}", e); 
     } 
    } 

    static void Hop() 
    { 
     CheckStackTrace(); 
     Hip(); 
    } 

    static void Hip() 
    { 
     CheckStackTrace(); 
     Hop(); 
    } 

    static void CheckStackTrace() 
    { 
     StackTrace s = new StackTrace(); 
     if (s.FrameCount > 50) 
      throw new Exception("Big stack!!!!"); 
    } 
} 
Cuestiones relacionadas