Geek Quizz VIII: vous avez dit static ?


A force de chercher des trucs vicieux…on en trouve :p.

Le programme suivant génère cette sortie. Quelle est la déclaration correcte de instanceCount ?

Ce que j’adore dans mon exemple c’est que l’on passe bien 12 fois sur instanceCount++ ! (on peut même mettre un point d’arrêt)

0
1
2

0
1
2

0
1
2

0
1
2

Press any key to continue . . .


public class TestClass<T>
{
? instanceCount
public TestClass()
{
Console.WriteLine(instanceCount);
instanceCount
++;
}
}

class Program
{
static void Main(string[] args)
{
Test();
new Thread(new ThreadStart(Test)).Start();
}

private static void Test()
{
for (int i = 0; i<3; i++)
new TestClass<string>();
Console.WriteLine(
);
for (int i = 0; i<3; i++)
new TestClass<int>();
Console.WriteLine(
);
}
}


[Update] Quizz suivant: Geek Quizz IX: constructeurs

Comments (10)

  1. Zim says:

    En ce qui me concerne, je ne vois pas le problème : la sortie est logique.

    La méthode Test() crée deux instances de la classe TestClass (avec deux types paramètres différent). Il n’y a aucune raison pour que instanceCount soit partagée entre les deux instances.

    Idem pour l’appel à Test() dans un nouveau thread : il n’y a aucun partage de variables …

    Ou alors j’ai loupé un truc.

  2. coq says:

    "Idem pour l’appel à Test() dans un nouveau thread : il n’y a aucun partage de variables …"

    Par défaut justement si, il faut un petit quelquechose en plus pour obtenir exactement la sortie proposée 😉

  3. Mitsu Furuta says:

    Ouarfff. Mea culpa ! J’ai rectifié. Mon exemple ne reflétait en effet pas du tout le point que je voulais soulever.

    C’est désormais corrigé. La question est donc toujours: quelle est la déclaration correcte de instanceCount ?

  4. [ThreadStatic] static int instanceCount.

    Je ne parle pas francais (je rappelle quelque chose mais j’etait trop petit … 12 ans …)

    Je dois commenter en anglais 🙂

    1) Having the type parameter T being of two different types  make the CLR Loader create two data structures in Loader Heap (2 reftypes would have their memory shared, but this is not the case here). 2) ThreadStatic attribute limits the "staticity" of a field to the thread scope.

    So … is this the answer you were thinking about ?

    Ciao

  5. Mitsu Furuta says:

    Hi Claudio ! You are right !!

    It’s nice to see people from foreign countries are also interested by my blog ! Where are you from ?

    En effet dans ce cas farfelu, je montre deux manières de réduire des variables statiques à des portées non globales.

    L’histoire des générics est facilement compréhensible. Tel les templates C++, on comprend que TestClass<string> et TestClass<int> génèrent à l’exécution deux classes distinctes qui ont leur propre définition et du coup leur propre exemplaire de instanceCount.

    Sous Windows, les allocations mémoire pour les données sont uniques par process et non partageables par défaut (il existe les fichiers mappés mémoires mais ce sont d’autres type d’allocation). Les structures système de type TLS (Thread Local Storage) permettent cependant d’isoler des allocations par thread dans un même process. C’est assez pratique pour isoler des données localement à un process et éviter certains conflits.

    .Net depuis sa première version utilise cette structure à travers l’attribut ThreadStatic qui rend une variable statique locale au thread d’exécution.

    Du coup dans notre exemple instanceCount repart à 0 lors de l’exécution par le second Thread.

  6. Hi 🙂

    I dug jut a little bit throughout your blog and it seems quite interesting … as far as I can tell, since as I told you I’m not a fluent French reader !

    I’m from Italy, living in Milan right now.

    I’ll keep reading your blog, which I have just subscribed to.

    And … well … a bientot 😉

    (hope the spelling is right, I’m trying to say "see you soon" …)

  7. coq says:

    Et puis ça marchait même avec l’ancien exemple, qui aurait ressortit la séquence 0, 0, 1, 1 sans attribut ThreadStatic 🙂

    Et que les développeurs ASP.NET n’y voient pas un moyen de rendre la valeur d’un champ statique limitée à une session ou une requête.

  8. Mitsu Furuta says:

    @Claudio: welcome in France ! I have another blog more technical oriented in english on http://blogs.msdn.com/mitsu

    @coq: En effet, de manière générale n’utilisez pas ThreadStatic avec le pool de Thread, c’est très dangereux. Réservez son usage à l’utilisation de vrais Threads.

  9. Ben oui ce n’est pas si simple ces histoires de portée. Une méthode peut être redéfinie par une classe