2012-07-07 15 views
8

Me preguntaba ...¿Bajo qué contexto estoy corriendo en C#?

Cuando tengo un código como el siguiente:

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

Puede MyAgent contener código que reconoce que se está ejecutando en un bloque lock?

¿Qué hay de:

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

Puede MyAgent contener código que reconoce que se está ejecutando en un bloque loop?

La misma pregunta se puede hacer para using bloques, unsafe código, etc ... - así se entiende la idea ...

Es esto posible en C#?

Esto es solo una pregunta teórica, no estoy tratando de lograr nada ... solo conocimiento.

+2

Bueno, creo que cada una de estas es una pregunta diferente. Puede haber algo para 'lock', pero' for' puede optimizarse y 'using' es solo una sintaxis para' try'/'finally'.De cualquier manera, en el tiempo de ejecución, muchos de estos no existen ... – Kobi

+0

No, nunca he oído hablar de tales cosas y dudo que existan estos mecanismos :) – GETah

+1

Creo que todos los desarrolladores de C# pueden responder. –

Respuesta

8

No es completamente imposible, puede usar la clase StackTrace para obtener una referencia al método del llamador y MethodInfo.GetMethodBody() para obtener el IL de ese método.

Pero nunca obtendrá esto confiable, el optimizador del compilador just-in-time le costará mucho averiguar exactamente dónde se encuentra la llamada. La incrustación del cuerpo del método hará que el método desaparezca por completo. El despliegue de bucle hará imposible obtener alguna idea sobre el índice de bucle. El optimizador utiliza registros de CPU para almacenar variables locales y argumentos de método, lo que hace imposible obtener un valor de variable confiable.

Sin mencionar el esfuerzo de masticación con hoja de estaño involucrado en descompilar IL. Nada de esto está cerca de la simplicidad y la velocidad de simplemente pasar un argumento al método.

3

No (código de restricción que reenvía explícitamente esta información al método, por supuesto).

La razón de esto es que conceptos como estos no se traducen en información estructurada que se conserva en IL o metadatos, que el CLR podría explicártelo en el tiempo de ejecución. Contraste esto con las clases que sí se codifican en metadatos, lo que permite la reflexión en tiempo de ejecución.

Intentar conservar esta información aumentaría la complejidad y, por supuesto, la sobrecarga adicional sin ningún beneficio, ya que es fácil implementar esto en el código si necesita mantenerlo (si es una buena idea requerir este estado). es otro problema).

0

No creo que .NET sea compatible con las características que describes directamente, aunque podrías obtener esa información usando StackFrame para tomar la pila de llamadas actual, y usar la reflexión para analizar cuerpos de métodos, etc. pero yo No estoy seguro de qué tan preciso puedas ser alguna vez.

.NET tiene contextos para la sincronización, pero no en el nivel que está preguntando. Consulte System.ContextBoundObject por ejemplo.

Cuestiones relacionadas