Question

J'ai un petit exemple de code:

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

La méthode GetAllItems permet d'accéder à la base de données et d'obtenir tous les nouveaux éléments de la collection - > tous les articles. Ensuite, la méthode 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;
                }
            }  
        }

Dans certains cas (dans HandleStatus1 et HandleStatus2), je dois accéder à la base de données, effectuer des mises à jour, puis remplir à nouveau la collection allItems en appelant la méthode GetAllItems.

Ce type de code lève une exception Stack.Overflow dans WinFormsApp. J'ai deux questions:
1. Ce type d’exception sera-t-il levé dans l’application WinService en utilisant le même code?
2. Quelle est votre opinion sur l’utilisation de minuteries au lieu de la méthode d’autoappel?

Était-ce utile?

La solution

Une "méthode de rappel automatique" est plus correctement appelée "méthode récursive" . Votre solution est créative, je vous le donnerai. Mais ne le fais pas. L'espace de pile est très limité. Vous verrez ce problème lorsque vous passerez à un service, et il existe de bien meilleurs moyens de le gérer. Une minuterie est très appropriée lorsqu'elle est utilisée dans un service.

Autres conseils

L'appel récursif de la méthode dans votre cas est aussi mauvais que d'utiliser un minuteur pour le faire. Vous devriez faire ni l'un ni l'autre!

Utilisez simplement une boucle et envoyez le fil en veille pendant un certain temps.

MS IL a un code de fonction .tail. Mais c # dot veut reconnaître la récursion de la queue (. Soit dit en passant, la récursivité de la queue est si lente dans .net ((

Pourquoi avez-vous besoin de récidiver? Aucune instruction de contrôle de flux ne permettra à la méthode d’arrêter de récursir et de quitter la chaîne. Les récursions infinies sont probablement la cause du débordement. Une meilleure solution serait de supprimer complètement la récursivité. Le fait de supprimer l’autre conteneur permet d’obtenir le même résultat sans avoir à récidiver:

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

Vous obtiendrez le même résultat sans rester coincé dans une boucle. Ensuite, vous pouvez implémenter des règles pour répéter l’appel dans le contexte de l’environnement d’exécution: un clic sur un formulaire ou un minuteur dans une application de service.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top