2011-01-28 22 views
8

Tengo una función recursiva en un BaseClass que se basa en una función protected virtual para su condición de retorno.Prevención de StackOverFlow en funciones recursivas

Es posible que una clase secundaria anule esta función incorrectamente y lleva a una excepción StackOverFlow. Lo peor es que hay algunas llamadas de red lentas y la excepción no va a suceder pronto (muchos recursos se desperdician durante mucho tiempo).

Estoy buscando un método para verificar StackOverFlow en etapas tempranas de alguna manera en la clase base (tal vez usando Reflection y el nivel de recursión actual).

¿Alguna idea?

+0

^votar por el tema sobre stackoverflow. – Robino

Respuesta

8

Usted podría pasar un entero simple 'profundidad' a la función recursiva y se incrementará con cada llamada posterior. Si es mayor que la profundidad máxima permitida, lanza una Excepción en ese momento en lugar de esperar hasta que sea demasiado tarde y se haya producido la temida excepción StackOverflow.

Tales mecanismos de seguridad (contador de incremento, compruebe que no es estúpidamente grande) también pueden ser útiles en los bucles while donde un pequeño error puede causar un bucle infinito que consume grandes cantidades de CPU.

En sistemas grandes con muchos usuarios (por ejemplo, sitios web) a veces es mejor tomar medidas de precaución como éstas con recursividad y bucles while porque las consecuencias pueden ir mucho más allá de una página web o un usuario del sistema. No es un código bonito y los puristas sin dudas se resistirán, pero es eficiente, es defensivo y es pragmático.

+3

De ninguna manera, Ian Mercer publica aquí? – Pierreten

+0

'bool RecursiveConditionMethod (ref int depthLevel) {depthLevel ++; // if (depthLevel> MAX_DEPTH_LEVEL) rompe el bucle '¿está bien? – Xaqron

+3

@Xaqron, no usaría ref int así. Simplemente pasaría profundidad + 1 cuando el método se llame a sí mismo y verifique la profundidad lo primero dentro del método. En una búsqueda en árbol, por ejemplo, es posible que no desee limitar los nodos totales visitados, pero es posible que desee asegurarse de que no se quede atascado en algún bucle porque el árbol no era un árbol correcto. –

1

Resuelva el problema en lugar de crear una solución alternativa. Crea una función privada recursiva que llama a la función virtual protegida.

+0

De ninguna manera. La condición de devolución no se revela a la clase base hasta el tiempo de ejecución, y esto se proporciona por clase secundaria al anular ese método. – Xaqron

+0

? ¿Por qué su clase base debería depender de una implementación anulada de clases secundarias? – Pierreten

+1

Las clases secundarias son complementos que comparten mucho trabajo a través de la clase base. Si un niño necesita ir en profundidad, está permitido, pero el código en sí está dentro de la clase base y se comparte entre los niños. – Xaqron

0

Aunque probablemente pueda leer la pila de llamadas y analizarla, no lo haría.

  1. que se ralentizará la ejecución
  2. No es su clase base responsabilidad
  3. Documento de su clase base comportamiento

Una alternativa podría ser la de hacer el análisis de la pila de llamadas en modo de depuración solamente. Aquí hay un pequeño código para ver cómo obtener la pila de llamadas.

using System.Diagnostics; 

[STAThread] 
public static void Main() 
{ 
    StackTrace stackTrace = new StackTrace();   // get call stack 
    StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) 

    // write call stack method names 
    foreach (StackFrame stackFrame in stackFrames) 
    { 
    Console.WriteLine(stackFrame.GetMethod().Name); // write method name 
    } 
} 

From this site

Cuestiones relacionadas