2012-07-07 14 views
8

mi chiedevo ...Sotto quale contesto sto correndo in C#?

Quando ho un codice come questo:

lock (obj) 
{ 
    MyCode.MyAgent(); 
} 

Può MyAgent contenere codice che riconosce che è in esecuzione in un blocco lock?

Che dire:

for (int i=0;i<5;i++) 
{ 
    MyCode.MyAgent(); 
} 

Può MyAgent contenere codice che riconosce che è in esecuzione in un blocco loop?

La stessa domanda può essere chiesto per using blocchi, unsafe codice, ecc ... - e si ottiene l'idea ...

Questo è possibile in C#?

Questa è solo una domanda teorica, non sto cercando di ottenere nulla ... solo la conoscenza.

+2

Bene, penso che ognuna di queste sia una domanda diversa. Potrebbe esserci qualcosa per 'lock', ma' for' può essere ottimizzato e 'using' è solo sintassi per' try'/'finally'.Ad ogni modo, in fase di esecuzione, molti di questi non esistono ... – Kobi

+0

No, non ho mai sentito parlare di queste cose e dubito che questi meccanismi esistano :) – GETah

+1

Penso che ogni sviluppatore C# possa rispondere. –

risposta

8

Non è completamente impossibile, è possibile utilizzare la classe StackTrace per ottenere un riferimento al metodo del chiamante e MethodInfo.GetMethodBody() per ottenere l'IL di tale metodo.

Ma non si otterrà mai questo affidabile, l'ottimizzatore del compilatore just-in-time vi darà un tempo molto difficile capire esattamente dove si trova la chiamata. L'allineamento del corpo del metodo farà sparire completamente il metodo. Lo srotolamento del loop renderà impossibile avere un'idea circa l'indice del ciclo. L'ottimizzatore utilizza i registri cpu per memorizzare variabili locali e argomenti del metodo, rendendo impossibile ottenere un valore variabile affidabile.

Per non parlare dello sforzo di masticazione della lamina di stagno coinvolto nella decompilazione di IL. Niente di tutto questo è vicino alla semplicità e alla velocità di passare un argomento al metodo.

3

No (codice di blocco che inoltra esplicitamente queste informazioni al metodo ovviamente).

La ragione di ciò è che concetti come questi non vengono tradotti in informazioni strutturate che vengono conservate in IL o metadati, che il CLR potrebbe quindi esporre all'utente in fase di runtime. Confrontalo con le classi che vengono codificate nei metadati, consentendo così la riflessione in fase di runtime.

Il tentativo di conservare queste informazioni comporterebbe una maggiore complessità e, naturalmente, un sovraccarico aggiuntivo senza alcun beneficio in quanto è facile implementarlo nel codice se si desidera che il programma mantenga tale stato (se è una buona idea richiedere questo stato è un altro problema).

0

Non credo che .NET supporti le funzionalità che descrivi direttamente, anche se potresti essere in grado di ottenere quelle informazioni usando StackFrame per afferrare lo stack di chiamate corrente e usando la reflection per analizzare i corpi del metodo ecc. Ma io non sono sicuro di quanto tu possa essere preciso.

.NET ha contesti per la sincronizzazione, ma non al livello che si sta chiedendo. Controlla ad esempio System.ContextBoundObject.

Problemi correlati