Question

Utilisation du .NET Micro Framework 4.1

J'ajoute les clés de chaîne suivantes (et les valeurs de chaîne, pas pertinente ici) à un Hashtable:

"eth::address"
"eth::netmask"
"eth::gateway"
"eth::dns"
"eth::port"
"com::baudrate"
"com::parity"
"com::databits"
"com::stopbits"
"com::handshake"
"com::read-timeout"
"com::write-timeout"
"drv::led-firmware-file"
"scr::width"
"scr::height"
"scr::colors"

Lors de l'ajout de ces au

Hashtable aucune erreur sont jetés.

Cependant, lorsque l'on examine les propriétés et le contenu de la table de hachage Je peux voir ce qui suit:

16 seaux, mais 6 d'entre eux ont une clé nulle et la valeur null. Ce sont toujours les mêmes.

Qu'est-ce que pourrait être la cause?

Mise à jour:

Il n'y a pas beaucoup de code à message:

var settings = new HashTable(16);
settings.Add("eth::address", "192.168.1.1");
//Keep adding the settings mentioned above

exceptions sont jetés Non, à la fin il y a 16 articles dans la table de hachage, en commençant par 3 les valides, quelques unes nuls, puis quelques unes valides, etc ....

Il n'y a rien d'autre impliqué que cela est simplement un test

L'outil est d'inspecter # VS2010

Si je tente d'obtenir l'une des valeurs qui « se sont perdues », une exception est levée:

var x = settings["eth::port"];

généreront:

A first chance exception of type 'System.Exception' occurred in mscorlib.dll
An unhandled exception of type 'System.Exception' occurred in mscorlib.dll


enter code here
Était-ce utile?

La solution

Pour prolonger la réponse de Volkan - vérifier la mise en œuvre interne d'une Hashtable pourrait trouver ce qui suit:

public Hashtable(int capacity) : this(capacity, (float) 1f)
{
}

public Hashtable(int capacity, float loadFactor)
{
    // arguments checking - elided

    this.loadFactor = 0.72f * loadFactor;
    double num = ((float) capacity) / this.loadFactor;
    if (num > 2147483647.0)
    {
        throw new ArgumentException(
            Environment.GetResourceString("Arg_HTCapacityOverflow"));
    }
    int num2 = (num > 3.0) ? HashHelpers.GetPrime((int) num) : 3;
    this.buckets = new bucket[num2];
    this.loadsize = (int) (this.loadFactor * num2);
    this.isWriterInProgress = false;
}

Alors qu'est-ce qui se passe lorsque vous initialisez avec new Hashtable(16) ...? Tout d'abord, la valeur de num est calculée à 16/0.72 = 22.(2). Puis, coups de pied dans HashHelpers.GetPrime(22), qui ressemble à ceci:

internal static int GetPrime(int min)
{
    // arguments checking - elided

    for (int i = 0; i < primes.Length; i++)
    {
        int num2 = primes[i];
        if (num2 >= min)
        {
            return num2;
        }
    }

    // more code; irrelevant in this case - elided
}

On y est presque. Nous avons seulement besoin de regarder ce que primes est.

static HashHelpers()
{
    primes = new int[] { 3, 7, 11, 17, 23 /* more values */ };
}

Avec 22 comme argument min, nous pouvons facilement voir les rendements de GetPrime 23. Telle est la valeur utilisée dans le constructeur de Hashtable pour créer tableau des seaux. Vous pouvez effectuer même analyse pour cadre micro pour voir pourquoi il crée 16 seaux (qui est TBH bizarre, étant donné qu'il est une bonne pratique pour le nombre de seaux pour être la valeur de choix).

Autres conseils

Je n'ai pas accès à cadre micro, mais pour .NET 4.0, je l'ai testé avec un échantillon que vous avez donné et il alloue 23 seaux, 7 d'entre eux a des valeurs nulles. Chaque valeur est placée dans le seau avec son code de hachage% 23. Par exemple, eth :: passerelle a le code de hachage de 1866092901 et son module 23 est 22 donc sa place dans le seau 22. Pourquoi vous inquiétez-vous sur les tables de hachage stratégie interne d'allocation de seau? Essayez le code ci-dessous dans LINQPad et vous pouvez être sûr:

void Main()
{
    string[] vals = {"eth::address", "eth::netmask", .. all other strings... };
    var ht = new Hashtable(16);
    foreach (var v in vals) 
          ht[v] = v;
    var m = typeof(Hashtable).GetField("buckets", BindingFlags.NonPublic | BindingFlags.Instance);
    m.GetValue(ht).Dump();
    ht.Dump();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top