2013-05-31 2 views
10

Ho un servizio Windows che utilizza una classe singleton ThreadQueue<T>. Quando il servizio viene avviato, effettua una chiamata a ThreadQueue<string>.Start(), quindi accetta e accoda le attività che limitano la concorrenza a un numero configurabile di thread.Strange System .__ Eccezione Canon

ThreadQueue<string>.Start() viene chiamato una volta sola una volta all'avvio del servizio.

A volte, dopo poche ore di servizio in esecuzione che ricevo la seguente eccezione:

Application: myservice.exe 
Framework Version: v4.0.30319 
Description: The process was terminated due to an unhandled exception. 
Exception Info: System.NullReferenceException 
Stack: 
    at Apollo.Business.Framework.Threading.ThreadQueue.ThreadQueue`1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Start() 
    at System.Threading.ThreadHelper.ThreadStart_Context(System.Object) 
    at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 
    at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 
    at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 
    at System.Threading.ThreadHelper.ThreadStart() 

Ciò che è e ciò che è System.__Canon rendendo questo passaggio in questo come un argomento di tipo di chiamata?

Qualcuno può far luce?

+1

Hai provato a compilarlo in modalità 'Debug'? – Ofiris

+0

E 'già, perché lo chiedi? – jaywayco

risposta

17

È necessario non leggere nulla nell'argomento metodo nome tipo. Sistema .__ Canon è un dettaglio di implementazione relativo al modo in cui i generici sono implementati nel CLR. Non conosco l'utilizzo esatto ma sospetto fortemente che sia utilizzato da Ngen.exe, lo strumento di ottimizzazione in .NET che esegue il pre-jits degli assembly. I generici sono un problema nel pre-jitting poiché il tipo concreto viene istanziato in fase di esecuzione. Otterrai più copie di un metodo che accetta un tipo di argomento di un parametro di tipo. Solo un metodo che gestisce qualsiasi tipo di riferimento, ulteriori metodi per ogni tipo di valore, se presenti. Sistema .__ Canon può essere il tipo sostitutivo che è il segnaposto per qualsiasi tipo di riferimento, consentendo a Ngen.exe di precedere tale metodo anche se non può indovinare quale tipo effettivo verrà utilizzato in fase di runtime. Qualcosa del genere.

La scarpa si adatta, Apollo.Business.Framework.Threading.ThreadQueue suona come il tipo di classe che è presente in una libreria di stile del framework che dovrebbe essere pre-jitted quando viene installato poiché era pensato per essere utilizzato da più programmi .

Quindi ignorare il nome del tipo, concentrarsi sull'eccezione effettiva. NullReferenceException è un'eccezione comune diovviamente. Nulla è altrimenti visibile dalla traccia dello stack che darebbe un indizio su cosa lo causa. Direi che a un problema di inizializzazione con quel framework "Apollo", qualche oggetto dovrebbe avere un valore ma è ancora nullo. Avere una sbirciata sul codice sorgente per il costruttore ThreadQueue dovrebbe dare un suggerimento. Una chiamata al fornitore per aiuto se non ce l'hai. Un bug in una versione di 8 anni del jitter non lo spiega bene, quei bug sono stati risolti molto tempo fa.

7

Ora che runtime e framework sono stati aperti, è molto più semplice rispondere a questo tipo di domanda. La definizione di __Canon è disponibile here. Citazione:

// Internal methodtable used to instantiate the "canonical" methodtable for generic instantiations. 
// The name "__Canon" will never been seen by users but it will appear a lot in debugger stack traces 
// involving generics so it is kept deliberately short as to avoid being a nuisance. 

[Serializable] 
[ClassInterface(ClassInterfaceType.AutoDual)] 
[System.Runtime.InteropServices.ComVisible(true)] 
internal class __Canon 
{ 
} 

Come il commento spiega, è un dettaglio di implementazione per i farmaci generici ed è l'abbreviazione di "canonica".