Entiendo por qué el código no funciona . No entiendo qué razones técnicas lo hacen, por lo que no recibimos un mensaje de error más explícito.

Mientras desarrollaba una aplicación netcore2, terminé haciendo una referencia circular con los constructores. Quiero decir que el constructor de una clase A creó una instancia de otro objeto de tipo B que crearía una instancia de un objeto de tipo A y así sucesivamente.

Aquí hay un fragmento de código simple para reproducir la creación de instancias circular que arroja un StackOverflowException en el compilador en línea I hizo ese ejemplo el.

public class A
{
    public A()
    {
        var b = new B();
    }
}

public class B
{
    public B()
    {
        var b = new B();
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        var a = new A();
    }
}

Sorprendentemente, en lugar de una excepción de stackoverflow, es un error 502.3 - Bad Gateway que IIS me da justo antes de que la aplicación se bloquee, lo que no proporciona mucha información sobre el problema subyacente. Esperaba que una llamada circular como esta fuera un patrón lo suficientemente fácil de detectar para que no solo fuera captado por un compilador, sino que incluso fuera señalado por VisualStudio 2017 o Resharper ultimate, pero nada me advirtió al respecto.

esto artículo así como este parece indicar que el problema podría ser un tiempo de espera, pero parece poco probable ya que la aplicación se bloquea en menos de dos segundos.

Simplemente no entiendo por qué no hay CircularConstructionException: esto suena bastante fácil de implementar y lo que es peor, ¿por qué IIS no arroja un StackOverflowException normal como el compilador en línea?

2
Mathieu VIALES 18 oct. 2017 a las 22:38

3 respuestas

La mejor respuesta

Creo que la respuesta correcta es que es una decisión de diseño de C #. Mientras que otras excepciones se capturan y se envuelven en una página de excepción en su caso, un StackOverflowException hace que el proceso finalice, lo cual es motivo para informar una respuesta 502.3 (informar una falla de conexión).


Desde la página de MSDN en StackOverflowException s:

En versiones anteriores de .NET Framework, su aplicación podría atrapar un objeto StackOverflowException (por ejemplo, para recuperarse de recursión ilimitada). Sin embargo, eso actualmente se desaconseja la práctica porque un código adicional significativo es requerido para atrapar de manera confiable una pila excepción de desbordamiento y continuar ejecución del programa .

Comenzando con .NET Framework versión 2.0, una excepción StackOverflowException el objeto no puede ser atrapado por un try-catch bloquear y el proceso correspondiente es terminado por defecto. En consecuencia, se recomienda a los usuarios que escriban su código para detectar y prevenir una pila Desbordamiento. Por ejemplo, si tu la aplicación depende de la recursividad, uso un contador o una condición de estado para terminar el ciclo recursivo. Nota que una aplicación que aloja el Common Language Runtime (CLR) puede especifique que el CLR descargue el dominio de aplicación donde la pila se produce una excepción de desbordamiento y deja que el proceso correspondiente continuar. por más información, ver Interfaz ICLRPolicyManager y Hospedar Common Language Runtime.

3
Matthew Steven Monkan 9 feb. 2018 a las 07:54

Simplemente no entiendo por qué no hay CircularConstructionException: esto suena bastante fácil de implementar

No hay nada ilegal en tiempo de ejecución sobre un objeto que instancia otro objeto, incluso del mismo tipo. El problema es que no has controlado la pila correctamente, por lo que un StackOverflowException es realmente apropiado. En este caso, podría decirse que el compilador podría detectar el problema, pero esa no es una excepción en tiempo de ejecución.

e incluso peor, ¿por qué IIS no está lanzando una StackOverflowException regular como el compilador en línea?

IIS probablemente no sabe por qué murió. Crea un proceso de trabajo para ejecutar su aplicación; ese proceso murió debido al desbordamiento de la pila. El proceso del host IIS devolvió un error que indica que el proceso de trabajo falló. Quizás "Bad Gateway" no sea el más claro, pero el host IIS no sabe nada sobre el desbordamiento de la pila. Simplemente sabe que su proceso de trabajo no responde o está muerto.

2
Jimmy 18 oct. 2017 a las 20:44

Esta clase lo llama tiempo infinitivo y causa desbordamiento de pila

public class B
{
    public B()
    {
        var b = new B();
    }
}
0
olpro123 18 oct. 2017 a las 20:35