Pregunta

Tengo una pequeña muestra de código:

private void MonitorItems()
        {
            if (someCondition)
            {
                dateSelected = DateTime.Now;
                GetAllItems();
            }
            else
            {
                if(allItems.Count>0)
                    CheckAllItems();
            }
            MonitorItems();
        }

El Método GetAllItems va a DB y obtiene todos los elementos nuevos para la colección - > todos los artículos. Luego, el método CheckAllItems:

private void CheckAllItems()
        {
            foreach (Item a in new List<Item>(allItems))
            {
                switch (a.Status)
                {
                    case 1:
                        HandleStatus1();
                        break;
                    case 2:
                        HandleStatus2(a);
                        break;
                    case 0:
                        HandleStatus0(a);
                        break;
                    default:
                        break;
                }
            }  
        }

En algunos casos (en HandleStatus1 y HandleStatus2) necesito ir a la base de datos, hacer algunas actualizaciones y luego volver a llenar la colección allItems llamando al método GetAllItems.

Este tipo de código está lanzando la excepción Stack.Overflow en WinFormsApp. Tengo dos preguntas:
1. ¿Se lanzará este tipo de excepción en la aplicación WinService, usando el mismo código?
2. ¿Cuál es su opinión sobre el uso de temporizadores en lugar del método de auto llamada?

¿Fue útil?

Solución

A " método de auto-llamada " se denomina más correctamente " método recursivo " . Tu solución es creativa, te lo daré. Pero no lo hagas. El espacio de la pila es muy limitado. Verá este problema cuando se mude a un servicio, y hay formas mucho mejores de manejarlo. Un temporizador es muy apropiado cuando se usa en un servicio.

Otros consejos

La llamada recursiva al método en su caso es tan mala como usar un temporizador para hacerlo. No deberías hacer nada!

Simplemente use un bucle simple y envíe el hilo a dormir durante algún tiempo en el medio.

MS IL tiene un código de operación .tail. Pero c # dot quiere reconocer la recursividad de la cola (. Por cierto, la recursividad de la cola es muy lenta en .net ((

¿Por qué necesitas recurrir? No hay una declaración de control de flujo que permita que el método deje de recurrir y salga de la cadena. Las recursiones infinitas es probablemente lo que está causando el desbordamiento. Una mejor solución sería eliminar la recursión por completo. Al eliminar el contenedor else se obtiene el mismo resultado sin tener que recurrir:

private void MonitorItems()
{
    if(someCondition)
    {
        dateSelected = DateTime.Now;
        GetAllItems();
    }
    if(allItems.Count>0)
        CheckAllItems();
}

Esto logrará el mismo resultado sin atascarse en un bucle. Luego puede implementar reglas para repetir la llamada en el contexto del entorno de ejecución: un clic en un formulario o un temporizador en una aplicación de servicio.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top