2011-04-05 3 views
6

Je cherche une réponse à ce que fait la méthode Array.Clear (...) sous les couvertures en C#. J'ai regardé l'IL, mais cela ne donne pas vraiment d'indices, car il appelle simplement la méthode System.Array :: Clear (...) dans mscorlib, qui appelle ensuite une partie non gérée du CLR que je ne peux pas observer.Que fait réellement Array.Clear sous les couvertures?

La raison pour laquelle je pose cette question, c'est que je reçois occasionnellement une SEHException lancée par mon appel à Array.Clear, et je n'arrive pas à comprendre pourquoi cela se produit.

Malheureusement, Microsoft semble être un peu loquace sur ce que cela pourrait vouloir dire quand l'exception est levée ...

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

« Toute exception SEH qui ne sont pas automatiquement mis en correspondance Par défaut, une exception spécifique est mappée à la classe SEHException.Pour plus d'informations, recherchez "Exceptions non gérées" et "Gestion des exceptions structurées" dans la bibliothèque MSDN. "

Toute aide à ce sujet serait appréciée ... juste pointez-moi dans la bonne direction, même!

Merci!

+0

Qu'est-ce que vous avez un tableau de ce que vous essayez d'effacer? Pourquoi type d'objets? – rsbarro

+0

Publiez la plus petite quantité de code reproduisant l'erreur. – jason

+0

Vous pouvez toujours décompiler la méthode avec le .NET Reflector (anciennement gratuit). Cela vous dira exactement ce qui se passe. –

Répondre

5

Vous pouvez voir ce type de code dans le code source SSCLI20. Ce qui ressemble à ceci avec tout le bruit enlevé:

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 d'autres termes, il explosions simplement 0 octets dans les éléments. La seule façon d'obtenir une SEHException est une erreur de processeur. GC tas de corruption. Passez en revue tout pinvoke ou code d'interopérabilité COM.

+0

C'est exactement ce que je cherchais ... Je ne peux pas vraiment poster de code pour le reprocher, car le code est intégré dans une assez grande application. Mais tout ce qui se passe réellement, c'est que j'essaye d'effacer un tableau d'octets de 4096 octets. Le problème est que l'erreur est incohérente, donc il n'y a vraiment aucun moyen d'écrire une application de test pour cela. –

+0

De plus, je n'ai pas de pinpin ou de code d'interopérabilité COM dans mon projet, donc cela ressemble plus à une sorte de corruption à un niveau inférieur à celui que je contrôle. –

+0

Douloureux. Ne considérez pas le CLR sauf si vous avez une ancienne version non corrigée. Quelque chose d'environnemental, de la merde qui s'injecte dans n'importe quel processus. Quelle est la valeur ErrorCode de l'exception? –

6

Il est plus facile de EnvisionArray.Clear en cours d'écriture comme si

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

Je me rends compte Array.Clear est pas vraiment une méthode générique, je suis en train de démontrer une correspondance étroite de ce qui se passe sous le capot . Vraiment si elle est plus proche de

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

Si ce code est de lancer un SEHException alors est la mémoire autour du réseau source est corrompue la cause la plus probable. La source la plus probable est un appel PInvoke ou COM interop incorrect.

Questions connexes