Domanda

Ho un piccolo esempio di codice:

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

Il metodo GetAllItems va su DB e ottiene tutti i nuovi elementi per la raccolta - > tutti gli articoli. Quindi, il metodo 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;
                }
            }  
        }

In alcuni casi (in HandleStatus1 e HandleStatus2) ho bisogno di andare al DB, fare alcuni aggiornamenti, quindi popolare nuovamente la raccolta allItems chiamando il metodo GetAllItems.

Questo tipo di codice genera l'eccezione Stack.Overflow in WinFormsApp. Ho due domande:
1. Questo tipo di eccezione verrà generato nell'applicazione WinService, utilizzando lo stesso codice?
2. Qual è la tua opinione sull'uso dei timer anziché sul metodo di auto-chiamata?

È stato utile?

Soluzione

Un metodo "auto-chiamante" è più correttamente chiamato " metodo ricorsivo " . La tua soluzione è creativa, te lo darò. Ma non farlo. Lo spazio dello stack è molto limitato. Vedrai questo problema quando ti trasferirai in un servizio e ci sono modi molto migliori per gestirlo. Un timer è molto appropriato se utilizzato in un servizio.

Altri suggerimenti

La chiamata ricorsiva al metodo nel tuo caso è non valida come usare un timer per farlo. Non dovresti fare nessuno dei due !!

Basta usare un semplice ciclo e inviare il thread in pausa per un po 'di tempo in mezzo.

MS IL ha un codice operativo .tail. Ma c # dot vuole riconoscere la ricorsione della coda (. A proposito, la ricorsione della coda è così lenta in .net ((

Perché hai bisogno di ricorrere a tutti? Non esiste alcuna istruzione di controllo del flusso che consentirà al metodo di interrompere il ripetersi e di uscire dalla catena. Le ricorsioni infinite sono probabilmente ciò che sta causando l'overflow. Una soluzione migliore dovrebbe eliminare del tutto la ricorsione. La rimozione del wrapper else consente di ottenere lo stesso risultato senza dover ricorrere:

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

Ciò otterrà lo stesso risultato senza rimanere bloccati in un ciclo. Quindi è possibile implementare le regole per ripetere la chiamata nel contesto dell'ambiente di esecuzione: un pulsante fa clic su un modulo o un timer su un'applicazione di servizio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top