2012-01-16 26 views
7

Quiero asegurarme de que mi aplicación web sea funcional y no ocasione problemas de rendimiento. Cuando busqué, encontré que uno de los problemas más comunes relacionados con el problema de rendimiento es el problema de "bucles infinitos".¿Cómo detectar y evitar bucles infinitos?

quiero preguntar:

Dónde empezar a comprobar que el código nunca causa bucles infinitos?

¿Hay artículos, consejos, instrucciones, ejemplos? Estaré agradecido.

ejemplo:

mayo de este código provocar un bucle infinito?

public static IEnumerable<SubjectNode> ReadSubjectNodes(string filePath) 
{ 
    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) 
    using (XmlReader xrdr = new XmlTextReader(fs)) 
     while (xrdr.Read()) 
      if (xrdr.NodeType == XmlNodeType.Element && xrdr.LocalName == "subject") 
       yield return new SubjectNode(xrdr.GetAttribute("id"), xrdr.GetAttribute("name"), xrdr.GetAttribute("short")); 
} 

Gracias de antemano

+1

Quizás ponga un límite superior enorme, es decir, 'int ReadCount = 100000; while (xrdr.Read() && ReadCount--> 0) ' –

+6

Esto probablemente no es lo que está buscando, pero el problema general de averiguar si un programa entra en un ciclo infinito o termina ([" detener el problema "] ] (http://en.wikipedia.org/wiki/Halting_problem)) no tiene solución. – svick

+0

¿Qué está haciendo exactamente el código? ¿Lo va a enviar al usuario o es una ejecución detrás de escena?Si está entregando resultados a un usuario, podría obtener los primeros 10 -> mostrar los resultados -> luego tener una navegación para ir de una página a la otra cada vez, solo iterando los siguientes 10 archivos. –

Respuesta

5

Bueno, que yo sepa que el código no se causa un bucle infinito - no es recursivo, y un XmlReader desde el sistema de archivos finalmente se quedará sin datos. Sin embargo, podría ser de larga ejecución. En algunos casos, agregar un cheque de cordura puede ser útil, esto podría ser un contador o un control en contra del tiempo. Por ejemplo:

public static IEnumerable<SubjectNode> ReadSubjectNodes(string filePath) 
{ 
    int safetyCheck = 10000; 
    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) 
    using (XmlReader xrdr = new XmlTextReader(fs)) 
     while (xrdr.Read()) { 
      if(--safetyCheck == 0) throw new SomeTypeOfException(); 
      ... more code 
     } 
    ... more code 
} 
+0

Muchas gracias. Pero, ¿hay algún consejo general si debería tener cuidado? –

2

El código que has publicado aquí tiene una condición de salida: Cuando el XmlTextReader llega al final de su corriente. Por lo tanto, no es un ciclo infinito.

Eso es lo que debes hacer para evitar esto: asegúrate de que cada ciclo tenga una condición que hará que salga. Es mucho más fácil hacerlo al escribir el código que revisarlo más tarde.

2

No hay forma de predeterminar de manera determinista si un ciclo se ejecutará infinitamente, excepto los que tienen un número de iteraciones definido en tiempo de compilación y no alteran el contador de iteraciones en su cuerpo.

Sólo tiene que escribir código buena que no es propenso a un bucle infinito: inspeccionar las condiciones dentro de los ciclos while y pensar en un caso en el que la fuerza causa un bucle infinito. Eso es.

1

Los bucles de infinate se producen cuando se realiza un bucle hasta que se cumple un parámetro (un bucle while), pero es posible que la cláusula while nunca se satisfaga para salir del bucle. Y por lo tanto, continúa para siempre.

También es posible causar un bucle recursivo, por el cual se llama a una función desde sí mismo (o similar), donde activará constantemente una función, pero nunca estará más cerca de salir.

while (xrdr.Read()), está bien siempre y cuando .Read() invoque automáticamente el movimiento al siguiente elemento. A lo que, como su xrdr no es una fuente infinita, eventualmente llegará al final y saldrá.

Cuestiones relacionadas