2011-04-05 19 views
6

Estoy buscando una respuesta a lo que hace el método Array.Clear (...) bajo las cubiertas en C#.¿Qué hace Array.Clear en realidad bajo las sábanas?

He mirado el IL, pero eso realmente no da ninguna pista, ya que simplemente llama al método System.Array :: Clear (...) en mscorlib, que luego llama a una parte no administrada del CLR que no puedo observar.

La razón por la que estoy preguntando esto, es que de vez en cuando obtengo una SEHException lanzada por mi llamada a Array.Clear, y no puedo entender por qué está sucediendo.

Por desgracia, Microsoft parece ser un poco hermético sobre lo que podría significar, cuando se produce la excepción ...

Desde: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.sehexception(v=VS.100).aspx

"Cualquier excepción SEH que no se asigna automáticamente a una excepción específica se asigna a la clase SEHException de manera predeterminada. Para obtener más información, busque "excepciones no administradas" y "Gestión de excepciones estructuradas" en MSDN Library. "

Cualquier ayuda en esto sería apreciada ... ¡simplemente apúnteme en la dirección correcta, incluso!

Gracias!

+0

¿De qué tienes una matriz que intentas borrar? ¿Por qué tipo de objetos? – rsbarro

+0

Coloque la cantidad más pequeña de código que reproduzca el error. – jason

+0

Siempre puede descompilar el método con el Reflector .NET (anteriormente libre). Eso te dirá exactamente lo que está pasando. –

Respuesta

5

Puede ver ese tipo de código en el código fuente SSCLI20. Que se parece a esto con todo el ruido eliminado:

FCIMPL3(void, SystemNative::ArrayClear, ArrayBase* pArrayUNSAFE, INT32 iIndex, INT32 iLength) 
{ 
    BASEARRAYREF pArray = (BASEARRAYREF)pArrayUNSAFE; 
    // error checks 
    //.. 
    char* array = (char*)pArray->GetDataPtr(); 
    int size = pArray->GetMethodTable()->GetComponentSize(); 
    ZeroMemory(array + (iIndex - lb) * size, iLength * size); 
} 

En otras palabras, simplemente explosiones 0 bytes en los elementos. La única forma de obtener una SEHException es a través de una falla del procesador. Corrupción del montón de GC Revise cualquier código de interoperabilidad de pinvoke o COM.

+0

Esto es exactamente lo que estaba buscando ... Realmente no puedo publicar el código para reproducir esto, ya que el código está incrustado en una aplicación bastante grande. Pero todo lo que realmente está sucediendo es que estoy tratando de borrar una matriz de bytes de 4096 bytes. El problema es que el error está apareciendo de forma inconsistente, por lo que realmente no hay forma de escribir una aplicación de prueba para ello. –

+0

Además, no tengo ningún código de interoperabilidad o COM de PinOke en mi proyecto, por lo que se parece más a algún tipo de corrupción en un nivel inferior al que tengo control. –

+0

Doloroso. No considere el CLR a menos que tenga una versión anterior no parcheada. Algo ambiental, basura que se inyecta en cualquier proceso. ¿Cuál es el valor ErrorCode de la excepción? –

6

Es más fácil de Envision Array.Clear están escribiendo al igual que

public static void Array.Clear<T>(T[] array) { 
    for (int i = 0; i < array.Length; i++) { 
    array[i] = default(T); 
    } 
} 

realizo Array.Clear no es en realidad un método genérico, estoy tratando de demostrar una correlación estrecha de lo que está pasando bajo el capó . Realmente sin embargo está más cerca de

memcopy(&array, 0, array.Length * sizeof(T)); 

Si el código está lanzando una SEHException continuación, la causa más probable es la memoria en torno a la matriz de origen está dañado. La fuente más probable es una invocación incorrecta de PInvoke o COM.

Cuestiones relacionadas