Astuces DotNet (Sébastien Courtois)

14/06/2010

Microsoft@E3 : Conférence Microsoft 2/2 (Kinect)

Filed under: E3, Hors Catégorie, Kinect, Natal, XBOX 360 — Étiquettes : , , , , , , — sebastiencourtois @ 22:29

La conférence de Microsoft à l’E3 a été l’occasion de voir enfin Kinect (Ex Natal) en action. (Les vidéos arriveront au fur et à mesure de leur publication par Microsoft).

  • Qu’est ce que Kinect ?

Kinect  (ex Projet Natal) est un accessoire à la xbox 360 composé de de capteurs et de caméras noir et blanc ainsi que de rayon infrarouge permettant ainsi de reconnaitre les mouvements d’une personne dans l’espace avec une bonne précision. Vous pouvez ainsi jouer sans manette. Le but (plus ou moins avoué) de Microsoft est tout simplement de fournir un concurrent à la Wii voire de la dépasser et ainsi conquérir le cœur des joueurs casuals.

Big Brother is watching you

Remarque : Certains d’entre vous auront peut être remarqué que l’utilisation des rayons infrarouge est aussi utilisé par la table Surface.

  • Comment ça marche en interne ?

Si vous vous demandez comment Microsoft a réussi à réaliser cet outil de reconnaissance de personnes, je vous conseille l’article suivant (en anglais). Pour faire simple, ils ont enregistré pendants des heures de nombreuses personnes se déplaçant devant l’accessoire en lui décrivant chaque mouvement (en gros, on lui montre 10 M photos de mains différentes en lui répétant que c’est une main… au bout d’un moment elle comprend et sait reconnaitre une main). Alliant ce gros flux de données corporelles et des algorithmes d’intelligence artificielle (Algorithmes génétiques+apprentissage à  mon avis), on obtient un système (appelé TheBrain).Celui-ci est capable de reconnaitre, à partir des flux vidéos, les parties du corps (30 parties du corps) et ainsi analyser les mouvements de chaque membre en temps réel (30 images/sec …). Il faut aussi rappeler que Kinect peut gérer plusieurs personnes en même temps ce qui montre que l’optimisation du système a du être poussée au maximum.

  • XBOX LIVE et Kinect

La démo faite à l’E3 est assez révélatrice des possibilités de la bête. Une personne se met devant sa télé et fait un signe de la main puis est reconnu directement par le système.Son avatar se met alors à bouger comme lui. Ainsi il a juste à pointé de la main vers la télé pour faire apparaitre un curseur (comme avec une Wiimote). L’utilisateur peut aussi parler et donner des ordres comme “Xbox Play Movie” pour le film sélectionné. Une combinaison des mouvements et de la parole (car Kinect contient un micro) est donc possible grâce à Kinect.

Il est aussi possible de chat par vidéo grâce à cette accessoire qui est monté sur un petit moteur. Celui-ci lui permet de suivre l’utilisateur lors de ses déplacement dans la pièce (pas plus loin … c’est une caméra pas un robot :)).

  • “The time of talk is over !!!” … Les jeux

On attendait beaucoup des jeux présentés pour cet accessoire. 8 jeux ont été présentés et ils seront au nombre de 15 au lancement de la console.

    • Kinectimals

C’est connu, les enfants adorent les animaux. Microsoft a donc créé un logiciel où l’on peut joueur avec des animaux grâce à Kinect. La démo a montré une gamine jouer avec un bébé tigre dans une forêt.Saut,roulade,faire le mort,sauter à la corde, la petite fille s’éclate avec son bébé tigre comme si c’était un vrai en lui donnant des ordres exécutés instantanément par le félin.

Remarque : La vidéo est une version courte de ce qui a été présenté.

Adorant les animaux (et surtout les bébés animaux), j’ai trouvé cette démo attendrissante d’autant que le “contact” animal/enfant semble bien rendu. Graphiquement, c’est assez beau (surtout la fourrure des animaux). Seul petit bémol tout de même avec la présence d’un flou continuel qui ne permet pas d’apprécier l’ensemble de l’environnement à sa juste valeur. Reste à savoir s’il y a un gameplay intéressant. On nous promet 40 animaux différents et 30 activités. J’ai un peu peur que cela ressemble trop au Eye Pet sur PS3 dont je trouvais le concept super (oui je suis un grand gamin :)) mais très limité au niveau activité.

Cela me rappelle une démo qui m’avait marqué l’an dernier lors de l’annonce de Natal :

    • KinectSport

Comme dit précédemment, Microsoft va pomper chez les concurrents et ne s’en cache pas. Ainsi KinectSport est une reproduction de WiiSport à quelque détails près. Tout d’abord le moteur graphique, même s’il reste un peu cartoon avec la possibilité de jouer avec ses avatars xbox, est graphiquement bien supérieur à ce qui se fait sur Wii aujourd’hui. De plus, il y a une plus grand variété d’épreuves : foot / bowling / athlétisme (course de haie, javelot,saut en longueur …) / ping pong  / boxe  / beach volley.

    • Kinect Joy Ride

Clone de Mario Kart avec sensiblement le même gameplay et graphiquement supérieur tout en restant cartoon (avatar xbox 360). Au vu de la démo, je n’ai pas trouvé ça si intéressant que ça. Reste à savoir quand je l’aurais en main.

    • Kinect Adventure

jeu d’aventure dans lequel vous devrez éviter des obstacles seul ou a plusieurs (sorte de tetris humain), vous devrez chevauchez des nuages ou encore descendre des chutes d’eau en canoé. Graphiquement joli (notamment le rendu de l’eau et des éclaboussures) mais toujours cartoon (avec les avatar). Semble assez fun en multi coopération.

    • YourShape (by UbiSoft)

Premier éditeur indépendant à dégainer sur Kinect, UbiSoft (cocorico) qui sort un clone de WiiFit : YourShape.Divisé en 4 grandes sections ( art martiaux, yoga,fitness, mini jeux), il permet de s’entrainer et/ou de se maintenir en forme tout en s’amusant. Certains diront que WiiFit est déjà là et que ce n’est qu’un clone de plus sur le marché du fitness. Toutefois le plus de YourShape est que, avec Kinect, les mouvements sont vérifié visuellement et non plus selon la pression (aléatoire parfois) sur la Wii board. La démo effectué de chacune des sections est sympathique.

 

    • Dance Central (by Harmonix)

Jeu de Dance qu’on pourrait qualifier de clone (encore !) de Just Dance sur Wii. Toutefois c’est encore la puissance de Kinect et la précision de la capture qui devrait permettre au jeu de s’imposer contre la précision aléatoire du jeu Wii (certains se reconnaitront :)). De plus les chorégraphies sont a base de routines bien expliquées et un mode entrainement pour les néophytes permet de rentrer facilement dans le jeu. Enfin le background est en 3D et reproduit vos mouvements :). Pour les musique, principalement de la pop,hip hop,r’n’b (Lady gaga, NoDoubt …).

 

    • Projet secret (by LucasArt)

Un projet initié avec LucastArt sur l’univers Star Wars a été dévoilé permettant à tous les fan-boys d’incarner un jedi en vrai. Un court vidéo de gameplay a été montré et … grosse déception. Les mouvements sont lent et les déplacements du sabre aléatoire parfois ne touchant pas l’ennemi qui tombe. Bref déçu par le gameplay et un moteur graphique correct mais sans claque visuelle (pourtant on joue pas avec un avatar là je crois). Le projet n’est pas prévu avant 2011 donc on espère que ce sera plus au point la prochaine fois.

    • Forza Motorsport Kinect

La référence des jeux de voiture sur XBOX reviendra en 2011 avec un jeu magnifique compatible Kinect. Quelques vidéos de gameplay qui ressemble au dernier opus et un essai d’une Ferrari très belle. ça promet d’envoyer du lourd et ça sera en 2011.

  • Remarques diverses :

Lorsque l’on joue à certains jeux, Kinect prend des photos,vidéos de vous en train de jouer. Celles-ci sont récupérables et il est possible de les envoyer sur Facebook (histoire de pourrir les albums des potes c’est génial).

Il y a une phase de reconnaissance plus longue lors de la première utilisation afin de scanner le corps et le reconnaitre rapidement les fois suivantes. Certains jeux arrivent à détecté lorsque l’utilisateur enlève ou met un vêtements (réalité augmenté dans les futurs jeux XBOX 360 … je vais chercher  ma cape harry potter :)).

  • Conclusion :

Sortie annoncé  : 4 Novembre 2010 aux US (inconnu en France… surement une semaine à un mois après). 15 jeux promis à la sortie. Les rumeurs annoncent un prix plus bas pour ces jeux que les jeux 360 habituels.

Prix : Inconnu pour le moment. Les rumeurs parlent de deux versions (une fixe et une avec caméra qui suit la personne). La version “suiveuse” serait la plus cher à 180 $.

Kinect sur PC : ??? 😦

Kinect via XNA : ??? 😦

Avis : Mitigé. Je suis très emballé par la technologie et je pense que, comme Surface, les développeurs n’ont pas encore pensé leur “Kinect” à fond. Donc on aura un grand temps d’expérimentation de la part des éditeurs avant de  trouver des nouveaux paradigmes de gameplay et de jeux (comme cela a été le cas pour la Wii). Mes grandes craintes sont le prix et la fiabilité du système qui promet beaucoup mais qui, d’après les rumeurs, ne marche pas si bien que cela (pour l’instant le  grand public n’a pas pu y toucher… cela changera peut être dès demain au salon).

Pour terminer, je dirais que Microsoft a frappé un grand coup ce soir mais risque d’avoir dégainé  trop tard face à une Wii déja trop implanté dans la culture vidéo ludique mondiale. Microsoft aurait sorti ce système il y a deux/trois ans,il aurait été les rois du pétrole. Aujourd’hui, il tente un coup de poker pour récupérer le public casual avec un très bon produit mais il néglige clairement les hardcore gamer qui l’ont fait vivre jusqu’à maintenant. En espérant que la sauce prenne …

Bonus : La vidéo de promotion :

Microsoft@E3 : Conférence Microsoft 1/2

Filed under: Débutant, E3, Hors Catégorie, Kinect, Natal, XBOX 360 — Étiquettes : , , , , , , — sebastiencourtois @ 21:59

La conférence Microsoft de E3 vient de se terminer.

Revenons un peu sur ce qui a été montré et annoncé (je mettrais les liens vidéos au fur et à mesure de leur parution

(Note : je parlerai de Kinect dans un post suivant) :

  • La XBOX a 10 ans
  • Metal Gear Rising (Sortie 2011)

Hidéo Kojima est venu présenter son Metal Gear Rising avec un trailer et quelques vidéos de gameplay. Au vue de ces vidéos, je pense que le coté infiltration a été mise de coté pour fournir un beat-them-all au sabre avec un moteur graphique/physique qui assez impressionnant/précis.

  • Gears of Wars 3 (Fin 2010 / 2011)

Démo de gameplay multi (à 4) en coopération. Environnement vaste et impressionant graphiquement. Le jeu reste bien bourrin avec un bestiaire.

  • Fable 3 (Sortie : Fin 2010)

Trailer  ultra rapide du dernier né de Peter Molyneux. Deux ans après le dernier épisode, je n’ai pas trouvé que le moteur graphique s’était grandement améliorer. Maintenant reste à voir le gameplay libre qui tient très à cœur à Peter. J’aurais aimé une petit annonce de compatibilité avec Kinect (surtout vu la démo impressionnante de l’E3 2009) mais il n’a rien dit. 

  • Kindoms (de Crytek)

Trailer énigmatique montrant un guerrier de l’antiquité en sang… ce qui étonne c’est que personne n’avait parlé d’un projet Crytek sur XBOX 360 (exclusif en plus) à part le très attendu Crysis 2… on reste quand même sur notre faim…  plus de réponses dans cet E3 ou en 2011.

  • Halo Reach

Une démo du jeu solo. Pas de grande nouveautés depuis la béta publique multi-joueurs.

  • XBOX LIVE :

Microsoft annonce qu’il y a 25 Millions d’utilisateurs inscrit sur la plateforme

Il est mainteinant possible de regarder/écouter les vidéos/musique/photos à plusieurs tout en chattant (vidéo/audio/text).

Un partenariat a été signé entre ESPN et Microsoft pour fournir du foot US (College football uniquement), Basket et Soccer directement sur le 360. Apparemment, ce service serait gratuit pour les membres XBOX LIVE GOLD (à vérifier).

  • XBOX 360 SLIM

Une nouvelle 360 est disponible dès aujourd’hui au même prix que la précédent. Elle inclus le WIFI (Norme N) par défaut + HDD 250 Go. Je pense aussi que les composants internes sont plus fiables que les versions précédents. Elle a été aussi complètement redesigné et est beaucoup moins encombrantes.

Conclusion et avis sur cette conférence :

Si on excepte Kinect, la conférence a été pauve en annonce et Microsoft a voulu privilégié le casual gaming par rapport aux hardcore gamer (Peter Molineux est resté 30 secondes chrono sur scène :)). On sent clairement une intention de vouloir marcher sur les platebande de la Wii… malheureusement avec 2 ou 3 ans de retard.

Bref pas grand chose à se mettre sous la dent à part du Kinect…

09/06/2010

[.NET 3.5] Attention lors de l’utilisation des lambdas/closures

Filed under: .NET, C#, C# 4, Hors Catégorie, Intermediaire — Étiquettes : , , , , — sebastiencourtois @ 13:05

Afin de commencer cette article, commençons par une petite devinette.

Quel sont les résultats de ces deux morceaux de code :

var actions = new List<Action>();
for (int i = 0; i < 10; i++)
    actions.Add(() => Console.WriteLine(i));

foreach (var action in actions)
    action();
var actions = new List<Action>();

for (int i = 0; i < 10; i++)
{
    int j = i;
    actions.Add(() => Console.WriteLine(j));
}

foreach (var action in actions)
    action();

La première réponse que vous avez du vous faire est que ces deux codes ont le même résultat : afficher les nombres de 0 à 9. En effet, on met des méthodes délégués dans une liste de délégués puis on parcourt cette liste afin d’exécuter le code de ces délégués. La seule différence entre les deux codes est l’utilisation d ‘une variable local j.

Et pourtant la réponse est :

  • Exemple 1 : 10 10 10 10 10 10 10 10 10 10
  • Exemple 2 : 0 1 2 3 4 5 6 7 8 9

Autre exemple dans le même genre :

var actions = new List<Action>();
string[] urls = 
{ 
   "http://www.url.com", 
   "http://www.someurl.com", 
   "http://www.someotherurl.com", 
   "http://www.yetanotherurl.com" 
};

for (int i = 0; i < urls.Length; i++)
{
    actions.Add(() => Console.WriteLine(urls[i]));
}
var actions = new List<Action>();
string[] urls = 
{ 
   "http://www.url.com", 
   "http://www.someurl.com", 
   "http://www.someotherurl.com", 
   "http://www.yetanotherurl.com" 
};

for (int i = 0; i < urls.Length; i++)
{
    int j = i;
    actions.Add(() => Console.WriteLine(urls[j]));
}
Résultat : IndexOutOfRangeException (Index was outside the

bounds of the array
Résultat : les liens du tableaux sont affichés
  • Les lambdas peuvent être nuire gravement à la santé … mentale des développeurs 

Etrange non ? Décompilons le tout première exemple afin devoir ce qui est effectivement exécuté.

Note : Pour une raison inconnue, je n’ai pas réussi à obtenir ceci depuis Reflector. J’ai donc récupérer le code de l’article original.

[CompilerGenerated]
private sealed class <>c__DisplayClass2
{
    // Fields
    public int i;

    // Methods
    public void <Main>b__0()
    {
        Console.WriteLine(this.i);
    }
}
[...]
var actions = new List<Action>();

<>c__DisplayClass2 localFrame = new <>c__DisplayClass2();
for (localFrame.i = 0; localFrame.i < 10; localFrame.i++)
{
	actions.Add(localFrame.<Main>b__0);
}

foreach (var action in actions)
{
	action();
}

Comme on peut le voir, le fait de créer une lambda en utilisant une variable extérieure à celle ci à entrainer la génération d’une classe (<>c__DisplayClass2") qui est utilisé pour stocker la valeur de cette variable (dans la varaible i) et une méthode (<Main>b__0) qui contient le code de la lambda.  Si on regarde le code du premier for, on s’aperçoit que cette boucle incrémente la variable i de la classe DisplayClass2. Donc, à la fin de la première boucle, la classe DisplayClass2 contient une variable i = 10 et la liste actions contient une référence vers la méthode de cette classe. Ainsi lors de la boucle d’appel actions, on se retrouve a appeler le code Console.WriteLine(i) <=> Console.WriteLine(10) !!!!

Si on résonne de la même façon sur l’exemple 2, on obtient un appel Console.WriteLine(urls[4]) ==> Exception.

  • Pourquoi l’utilisation d’une variable locale résout le problème

Si on regarde le code ci dessous, on s’aperçoit que le problème vient du fait que la classe DisplayClass2 est créé en dehors de la boucle for et que celle ci utilise la variable i comme compteur. Le fait d’utiliser une variable temporaire à l’intérieur de la boucle for, oblige le compilateur à créer plusieurs instance de DisplayClass (une par itération). On obtient ainsi quelque chose comme le code suivant.

for (int idx = 0; idx < 10; idx++)

{

    <>c__DisplayClass2 localFrame = new <>c__DisplayClass2();

    localFrame.i = idx;

    actions.Add(localFrame.<Main>b__0);

}

Remarque : On pourrait penser que chaque instance est dispose lors de la sortie du scope. Cela n’’est pas vrai car la liste actiosn conserve une référence sur l’objet (en l’occurence sur une de ses méthodes) donc le garbage collector ne prend pas cet objet.

  • Conclusion

Les lambdas sont aujourd’hui utilisé dans de nombreuses technologies .NET (LINQ,PFX…) et sont une bonne alternative aux délégués classiques. Toutefois, on peut voir que cela peut engendré une certaine confusion voire des bugs lorsqu’on les utilise.

Je vous mets le lien vers l’article dont je me suis fortement inspiré pour cet article : Lambdas – Know your closures

10/05/2010

[Nouveautés C# .NET 4] Code Contracts : Mettre ses contrats sur des interfaces

Filed under: .NET, C# 4, DevLabs, Hors Catégorie, Intermediaire — Étiquettes : , , , , , — sebastiencourtois @ 15:30

Ce post fait suite à une introduction sur les Code Contracts publié précedement.

Les codes contracts permettent de spécifier et contrôler des règles au sein de votre code. Dans l’optique de la création d’API, il est interessant d’utiliser les Code Contract au sein de classe mais il est encore plus judicieux de les utiliser sur des interfaces (notamment pour les tests unitaires / IoC …). Nous allons donc voir comment réaliser des “code contracts” sur des interfaces.

  • Pour cela mettons nous en situation …

public interfaceIPerson
{
    void SetAge(int age);
}

public interfaceICustomer : IPerson
{
    void SetId(int Id);
}

public classPerson: IPerson
{
    protected int Age { get; set; }

    public void SetAge(int age)
    {
        this.Age = age;
    }
}

public classCustomer: Person,ICustomer
{
    protected int Id { get; set; }
    public void SetId(int id)
    {
        this.Id = id;
    }
}

Nous créons deux interfaces IPerson pouvant modifier l’age d’une personne et ICustomer dérivant de IPerson (donc on pourra modifier son age aussi) où l’on pourra modifier son Identifiant client. Ces deux interfaces ont été implémenté dans deux classes Person et Customer. Si on prend le scénario de la création d’une API, le créateur de l’API aura défini et manipulera les interfaces et le développeur utilisant l’API, aura implémenté les deux classes.

  • Comment le créateur de l’API peut définir des spécifications sur les paramètres de ses interfaces ?

Le but pour le créateur de l’API est de fournir un modèle de développement. Il peut ainsi indiquer les méthodes et les types à utiliser mais ne peut pas avoir plus de précision quand au contenu des paramètres. On a vu, qu’avec Code contract, il peut définir ces informations au sein des méthodes. Cela reviendrait à créer une classe abstrait (pas toujours pertinent surtout dans un langage où il n’y a pas d’héritage multiple comme le C#).

Pour définir un code contract sur une interface, quatre étapes sont nécessaires :

  1. Créer une classe contrat héritant el ‘interface sur laquelle on souhaite faire le contrat.
  2. Implémenter les méthodes de l’interface dans la classe de contrat en fournissant les code contracts.
  3. Décorer l’interface avec l’attribut ContractClass en fournissant le type de la classe de contract
  4. Décorer la classe avec l’attribut ContractClassFor en fournissant le nom des interface qui sont régit par le contrat
[ContractClass(typeof(PersonContracts))]
public interface IPerson
{
    void SetAge(int age);
}

[ContractClassFor(typeof(IPerson))]
public class PersonContracts : IPerson
{
    public void SetAge(int age)
    {
        Contract.Requires(age > 0 && age < 120, "L'age doit être compris entre 1 et 120 ans.");
    }
}

Le tour est joué. Ainsi pour le code exemple devient :

[ContractClass(typeof(PersonContracts))]
public interface IPerson
{
    void SetAge(int age);
}

[ContractClassFor(typeof(IPerson))]
public class PersonContracts : IPerson
{
    public void SetAge(int age)
    {
        Contract.Requires(age > 0 && age < 120, "L'age doit être compris entre 1 et 120 ans.");
    }
}

[ContractClass(typeof(CustomerContracts))]
public interface ICustomer : IPerson
{
    void SetId(int Id);
}

[ContractClassFor(typeof(ICustomer))]
public class CustomerContracts : PersonContracts,ICustomer
{
    public void SetId(int Id)
    {
        Contract.Requires(Id > 0, "L'identifiant doit être supérieur à 0.");
    }
}

Le code ci dessus est fait par le créateur de l’API.

public class Person : IPerson
   {
       protected int Age { get; set; }

       public void SetAge(int age)
       {
           this.Age = age;
       }
   }

   public class Customer : Person,ICustomer
   {
       protected int Id { get; set; }
       public void SetId(int id)
       {
           this.Id = id;
       }
   }

Le code ci dessus est fait par l’utilisateur de l’API. Il n’a pas à se préoccuper des contrats définis dans l’API et peut définir ses propres contracts.

08/05/2010

[MS Research / DevLabs] Accelerator v2 : Exploiter vos GPU facilement en .NET

Filed under: .NET, DevLabs, Hors Catégorie — Étiquettes : , , , , , , , , — sebastiencourtois @ 17:47

Suite à ma visite sur les sites Internet de Microsoft Research et DevLabs, j’ai décidé de vous parler de ces projets de Microsoft qui seront dans les prochaines versions de .NET (ou pas). Dans les anciens project MS Research que l’on retrouve aujourd’hui au grand public, on pourrait cité WPF/Silverlight,Surface,PFX…

De ce post, nous allons parler d’une technologie dont le nom de code est “Accelerator”.

  • Présentation du contexte

De nos jours, les fabricants d’ordinateur nous fournisse des processeurs toujours plus puissants que ce soit en fréquence d’horloge qu’en nombre de cœurs. Ces nouvelles possibilités commencent à être exploiter correctement (notamment grâce à PFX de .NET 4).

Mais ce qui est moins exploiter est la puissance de calcul des cartes graphiques (GPU). Il faut savoir qu’une carte graphique peut avoir plusieurs processeurs dont chacun peut avoir de nombreux coeurs (jusqu’à 500 pour les plus récentes). Tout ce potentiel n’est utilisé que pour les jeux afin de faire des rendus et des calculs mathématiques afin de rendre des scènes 3D.

Le gros avantages des GPU est sa rapidité de calcul et sa gestion optimisé du parallélisme.

En revanche, les défauts des GPU par rapport aux CPU :

  • Les instructions sont limités aux opérations mathématiques 3D alors que le CPU peut avoir des opérations plus génériques
  • Les instructions dépendent beaucoup du constructeurs de la carte graphique (beaucoup plus que pour un CPU)
  • Il y a très peu d’API permettant d’accéder aux GPU directement (sans passer des API 3D).
  • Qu’est ce qu’Accelerator ?

L’idée du projet Accelerator est de fournir une API (Managé et C++) permettant d’envoyer du code sur ces GPU qu’il l’exécute.

D’autres ont déjà eu l’idée avant Microsoft :

  • Nvidia avec CUDA
  • ATI avec ATI Stream
  • Appel avec OpenCL
  • “Pixel Shaders”

Bien que ces API existent (encore au stade BETA pour la plupart), Microsoft a décidé de créé le projet Accelerator afin de fournir une API de développement pour les GPU indépendant de la plateforme et extensible.

  • Comment cela fonctionne ?

Accelerator se compose de deux gros blogs : Accelerator Library et Target Runtime.

image Structure général d’une application Accelerator

L’”Accelerator Library” est une API de développement pour préparer les données afin d’être exécutés sur le GPU. Cela se base sur un système abstrait à base d’arbre d’expression (nous le verrons plus loin). Cette API est composé d’une partie Native (C++) et d’une partie Managé (wrapper léger sur l’API native).

Le “Target Runtime” est une sorte de driver permettant de faire communiquer l’API avec les couches matériels (GPU … mais aussi CPU Multicore). Ce driver lit les arbres d’expressions d’”Accelarator Library” et envoie les instructions correspondantes aux GPU. Le driver est aussi en charge de la gestion de la charge sur les processeurs/cœurs. Microsoft fournit deux target runtime par défaut : Un DirectX9 (permettant d’accéder indépendamment à l’ensemble des carte graphiques du marché) et un pour les multi-coeurs CPU 64bits. Si vous souhaitez utilisé Accelerator sur d’autres types de processeurs, il suffit de développer un target runtime pour l’architecture cible.

Afin de comprendre le fonctionnement de Accelerator Library, prenons un exemple. Prenons deux tableaux contenant des valeurs à virgules flottantes (float). On souhaite additionner les cases une à une dans un troisième tableaux. Sur un CPU, on aurait une boucle for qui ferait les opération dans l’ordre des cellules et une cellule à la fois.

acceleratorv2 Exécution d’une addition sur un tableau (Sequential Program = CPU / Data Parallel Program = GPU)

Sur le GPU, le tableau est divisé et chaque cœurs à son propre lot de données à exécutés. Après exécution, le tableau est réassemblé à partir des résultats des tableaux de chacun des cœurs.

Afin que les opérations soient abstraites par rapport aux matériels sous jacent, Accelerator fournit un système d’arbre permettant de faciliter la création des instructions GPU. Par exemple, le graph suivant représente l’addition case par case de deux tableau puis la division de chacun des cases résultat par 2.

image Arbre d’expression Accelerator

  • Comment installer Accelerator ?

Accelerator v2 est actuellement disponible sur https://connect.microsoft.com/acceleratorv2.

Une fois installé, vous avez accès à  un document d’introduction et un document contenant l’ensemble des classes du projet. Je vous conseille le document d’introduction qui est très bien fait (j’en reprend un partie dans ce post).

Afin de développer, vous devez ajouter en référence l’assembly Microsoft.Accelerator.dll (contenu dans le répertoire C:\Program Files\Microsoft\Accelerator v2\bin\Managed).

Attention : Pour l’exécuter, il est nécessaire de placer la dll Accelerator.dll (se trouvant dans le répertoire C:\Program Files\Microsoft\Accelerator v2\bin\x86 ou C:\Program Files\Microsoft\Accelerator v2\bin\x64 selon votre architecture ) dans le répertoire où s’exécute l’application sous peine d’avoir l’exception : “DllNotFoundException : Unable to load DLL ‘Accelerator.dll’: Le module spécifié est introuvable. (Exception from HRESULT: 0x8007007E)”

  • Un Hello world “Accelrator”

En reprenant l’exemple d’addition case à case puis d’une division par 2, on obtient un code C# suivant (le reste du code a été enlevé afin de pas alourdir le code).

On commence par simplifier le code en utilisant des using.

using FPA = Microsoft.ParallelArrays.FloatParallelArray;
using PA = Microsoft.ParallelArrays.ParallelArrays;

FloatParallelArray représente un tableau de float sur la cible (carte graphique dans notre cas).. ParallelArrays regroupe les instruction disponible pour la cible.

DX9Target evalTarget = new DX9Target();

On crée le driver qui sera utilisé pour exécuter les opérations. Afin de faire simple, nous utiliserons le driver DirectX9 afin d’accéder aux GPU.

float[] inputArray1 = new float[arrayLength];
float[] inputArray2 = new float[arrayLength];
float[] stackedArray = new float[arrayLength];
/* Ajout de données dans les tableaux  inputArray1/inputArray2 */

On crée trois tableaux. Deux tableaux contenant les données d’entrée (inputArray1,2) que l’on remplit de valeurs diverses et un tableau pour les résultats.

FPA fpInput1 = new FPA(inputArray1);
FPA fpInput2 = new FPA(inputArray2);

On “transforme” les tableaux afin qu’il soit utilisables pour la cible.

FPA fpStacked = PA.Add(fpInput1, fpInput2);
FPA fpOutput = PA.Divide(fpStacked, 2);

On crée les opérations entre les tableaux. On utilise le résultat de l’addition pour la division. Cela génère l’arbre d’expression en copie d’écran plus haut.

evalTarget.ToArray(fpOutput, out stackedArray);

C’est la partie la plus importante du programme. En effet, jusqu’à maintenant nous avons préparé l’arbre d’expression et les données et c’est sur cette méthode, que l’arbre est évalué et que la cible (GPU dans notre cas) réalise les opérations. Le résultat est ensuite convertir et stocké dans un tableau de float .NET.

  • Et les performances alors ?

Il  est vrai que tout ça est un peu contraignant alors on est en droit de se demander si les performances sont aux rendez vous. Sur l’exemple ci dessus par exemple sur ma machine, les performances étaient meilleures en .NET qu’en GPU. La raison est, selon moi, que le temps de copie et d’éxécution est long pour le peu d’opérations exécutées.

Pour des données plus claires sur le domaine, je vous renvoie sur le PDF de MS Research parlant des performances : Document PDF . On peut voir que les performance peuvent être jusqu’à 70x plus rapide sur certains code par rapport au C++ sur CPU.

Le kit de développement contient aussi des samples (dont un jeu de la vie) qui permettent un peu de se rendre compte de ces performances.

Il est nécessaire de rappeler que ce projet est en alpha et donc loin d’être optimisé.

  • Conclusion

Ce projet est plein de promesses même s’il reste en dessous de technologies comme CUDA qui se rapproche du langage C alors que Accelerator est basé sur des arbres d’expressions / opérations mathématiques de bases. De plus Accelerator étant basé sur le parallélisme, il est nécessaire de rappeler que, comme PFX, tous les algorithmes ne sont pas faits pour ces technologies.

  • Quelques liens utiles :

Site du projet sur Microsoft Research (Attention c’est la v1 sur ce site)

Téléchargement de la v2

Article d’un français sur le sujet : Accelerator & F# / Accelerator : F# vs C#

03/05/2010

[.NET] Immutabilité et chaines de caractères en .NET

Filed under: .NET, C#, Débutant, Hors Catégorie, Intermediaire, Optimisation — Étiquettes : , , , , , , , — sebastiencourtois @ 15:31

Nous avons vu brièvement lors d’un post précédent un objet “immutable” (en anglais, immuable en vrai français) : Le Tuple”. Toutefois, nous ne sommes pas rentrés dans les détails de ce type d’objet et nous n’avons pas étudié le plus utilisé de tous : La classe String.

  • Définition de l’immutabilité

Un objet “immutable” est une objet dont les propriétés sont définies à la création de l’objet puis ne peuvent plus changer durant la vie de l’objet.

Une des raisons de la création de ce type d’objet (c’est d’ailleurs aussi un design pattern) : la gestion de la mémoire. En effet, vu que les données sont créées à la création de l’objet, il suffit d’allouer l’ensemble de la mémoire d’un coup et de ne plus y toucher jusqu’à la destruction de l’objet.

Un autre avantages est le multithreading. En effet, si l’objet n’évolue pas au cours de sa vie, tous les threads peuvent y accéder quand ils veulent sans avoir besoin de se synchroniser. Cela permet une programmation plus simple et un programme plus rapide.

  • Exemple concret d’immutabilité : String

Un objet “immutable” que nous utilisons tous les jours sans le savoir spécialement : la classe string.

Prenons l’exemple C/C++ suivant :

#include <stdio.h>
#include <string.h>

int main(int argc,char **argv)
{
    char *test = new char[7];
    strcpy(test,"Bonjour");
    printf("%c",test[2]);
    test[2] = 'N';
    printf("%c",test[2]);
}

Le programme copie une chaine (“bonjour”) dans un tableau de caractère puis affiche le 3ème caractères (‘n’) puis décide de modifier ce troisième caractères et de le réafficher. Tout cela se passe normalement, on obtient “BoNjour” à la fin de l’éxécution du programme.

Prenons le même type de programme en C# avec une string.

static void Main(string[] args)
{
    string test = "Bonjour le monde !!!";
    Console.WriteLine(test[2]);
    test[2] = 'N';
    Console.WriteLine(test[2]);
}

Rien ne laisse présager un problème, on utilise System.String comme une tableau de caractère et on modifie sa troisième valeur. Et pourtant on obtient l’erreur suivante :

immutable1

Un petit tour sur le code de la classe System.String et on voit en effet que l’indexer est uniquement en GET :

// Summary:
//     Represents text as a series of Unicode characters.
[Serializable]
[ComVisible(true)]
…….
    // Summary:
    //     Gets the character at a specified character position in the current System.String
    //     object.
    //
    // Parameters:
    //   index:
    //     A character position in the current string.
    //
    // Returns:
    //     A Unicode character.
    //
    // Exceptions:
    //   System.IndexOutOfRangeException:
    //     index is greater than or equal to the length of this object or less than
    //     zero.
    public char this[int index] { get; }

On peut donc voir que la classe String est bien immutable car sa valeur est fixé à sa création et après la chaine devient read only.

  • Les méthodes de la classe System.String

Vous pourriez vous dire, à raison, que la classe string contient des méthodes permettant modifier la chaine après création (ToUpper/ToLower). Or si vous remarquez bien, l’ensemble de ces méthodes retournent un type string. La chaine en paramètre est la chaine d’entrée et restera toujours à la même valeur alors que la valeur de retour sera une nouvelle chaine traité à partir de la première.

Un petit exemple tiré de la MSDN démontrant cela :

class Program
{
  static void Main(string[] args)
  {
     string testString = "A TEST STRING"; Console.WriteLine("testString: " + testString + Environment.NewLine);
     Console.WriteLine("Performing 'testString.ToLower();'");
     // Does not alter the string. Returns a new lowercase string, but           
     // we do not assign it to anything, so it is discarded            
    testString.ToLower();
    Console.WriteLine("testString: " + testString + Environment.NewLine);
    Console.WriteLine("Performing 'string lowerString = " + "testString.ToLower();'");
    // Assign the returned string to a new variable           
    string lowerString = testString.ToLower();
    Console.WriteLine("lowerString: {0}{1}testString: {2}{1}",
    lowerString, Environment.NewLine, testString);
    // Finally convert the test string to lowercase by assigning the             
    // result of ToLower back to itself. Note that this still doesn't            
    // result in the original testString object changing; instead, the            
    // old testString is discarded and the variable is set to the newly-            
    // created lowercase string object           
    Console.WriteLine("Performing 'testString = testString.ToLower();'");
    testString = testString.ToLower();
    Console.WriteLine("testString: " + testString);
    Console.ReadLine();
  }
}

  • Cas de la concaténation de chaines

L’utilisation du caractères ‘+’ pour la concaténation de chaines s’est énormément répandu depuis la sortie du .NET. Toutefois, il faut savoir que cela peut être désastreux pour les performance. En effet, chaque utilisation de ‘+’ entraine la création d’une nouvelle chaine.  Ainsi l’ajout de 1000 caractères un à un avec le caractère ‘+’ va entrainer la création de 1000 chaines de caractères allant de 0 à 999 caractères (999! caractères pour les matheux).

Dans ce cas, on préconise l’utilisation de la version “mutable” (comprendre : modifiable) de System.String : StringBuilder. On peut voir l’intérêt dans le test suivant :

static void Main(string[] args)
{
    for (int nb = 1; nb < 1000000; nb *= 10)
    {
        Stopwatch sw = Stopwatch.StartNew();
        string s = "";
        for (int i = 0; i < nb; i++)
            s += "T";
        sw.Stop();
        Console.WriteLine("Temps string \t {0} \t: {1}", nb, sw.Elapsed);

        Stopwatch sw2 = Stopwatch.StartNew();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < nb; i++)
            sb.Append("T");
        sw2.Stop();
        Console.WriteLine("Temps SB \t {0} \t: {1}", nb, sw2.Elapsed);
    }
    Console.ReadLine();
}

Résultat du test de performance :

Nombre Concaténation Temps String Temps StringBuilder
1,00 00:00:00.0000015 00:00:00.0000034
10,00 00:00:00.0000076 00:00:00.0000007
100,00 00:00:00.0000138 00:00:00.0000026
1 000,00 00:00:00.0011658 00:00:00.0000211
10 000,00 00:00:00.0388231 00:00:00.0001182
100 000,00 00:00:05.4556546 00:00:00.0011412

Le résultat est sans appel en faveur de StringBuilder qui est jusqu’à 500x plus rapide que la concaténation avec le caractère +.

  • Conclusion

Il faut donc faire attention lorsque l’on utilise des objets du framework afin de savoir s’ils sont “mutables” ou non car, bien qu’un objet “immutable” soit là pour permettre des meilleurs performances, cela peut s’avérer le contraire lorsqu’il est mal utilisé (exemple string VS StringBuilder).

26/04/2010

[Nouveautés .NET 4] Task Parallel Library : Gestion des architectures multicores/multiprocesseurs

Filed under: .NET, C# 4, Débutant, Hors Catégorie, Optimisation — Étiquettes : , , , , , , , , — sebastiencourtois @ 09:55

De nos jours, on ne trouve plus dans le marché de la vente d’ordinateurs que des architectures avec des processeurs double,quad,octo…. cores (et parfois même multi processeurs). Malgré cette débauche de puissance de calculs, il est triste à noter que nos applications ne sont, pour la plupart, pas tellement plus rapide qu’avant. La cause :

  • Les développeurs ne savent généralement pas coder des applications gérant plusieurs threads

PFX1 Ca fait mal d’avoir 4 coeurs et d’en utiliser qu’un seul… à moitié !!!

C’est un fait. Lorsque l’on apprend la programmation, on nous enseigne généralement beaucoup de choses mais rarement comment faire des applications gérant correctement plusieurs threads. L’une des raison est simple : Les API de développement sont généralement complexes et demande des efforts d’architecture/programmation/débug afin de rendre le tout utilisable. WaitHandle,Process,Mutex,lock,Interlocked … autant de mot clé et concepts barbare que le développeur doit maitriser afin de pouvoir décupler la puissance de ses applications. “On a déja du mal à faire une application correspondant aux spécifications dans le temps imparti, on va pas en plus passer des heures à gérer les multi coeurs”.

Partant de ce constat, Microsoft a créé Parallel FX afin d’aider le développeur à gérer facilement les threads au sein de ses applications.

  • Organisation de TPL

TPL se compose de 3 namespaces NET 4 :

  1. System.Threading.Tasks : Ce namespace contient la base de Task Parallel Library (TPL), il contient la classe principale de la technologie : la classe Tasks (sorte de “super Thread”)
  2. System.Collections.Concurrent : Ce namespace contient les collections pouvant être utilisé dans des contextes multithreads (thread safe).
  3. System.Linq : LINQ a été amélioré pour intégrer des aides au multithreading. Connu sous le nom de PLINQ (Parallel LINQ), il permet de paralléliser certaines étapes des requêtes LINQ afin de les rendre plus rapide.
  • Le namespace System.Threading.Task

Ce namespace contient une classe Task. Cette classe représente une opération asynchrone. Ainsi on défini notre tache et, lorsqu’on la démarre, celle-ci est assigné par le TaskScheduler à un des coeurs disponibles de la machine. Ce système marche sous la forme d’une  file (first in / first out) de priorité (il y a des VIP :)). Ce Taskscheduler est aussi capable de distribuer un grand nombre de tâches aux différentes cœurs et de balancer la charge si un cœur est plus occupé qu’un autre (un peu à l’instar des load balancing dans les serveurs web).

La création et l’utilisation des Task est simple :

Task t1 = Task.Factory.StartNew(() =>
    {
        for (int i = 0; i < 200; i++)
        {
            if(i % 2 == 0)
                Console.WriteLine(i+" ");
        }
    });

Task t2 =new Task(() =>
{
    for (int i = 0; i < 200; i++)
    {
        if (i % 2 == 1)
            Console.WriteLine(i + " ");
    }
});
t2.Start();

Il y a,au moins, deux méthodes pour créer une Task. La première en utilisant une fabrique d’objet fournit par la classe Task. La seconde est de créer soi même une classe Task et de lui fournir la méthode à éxécuter puis de le lancer en appelant la méthode Start (un peu de la même façon qu’un thread. Il est à noter que l’on ne peut fournir de méthode retournant de valeurs. De plus, la méthode doit être sans paramètre ou alors avec un seul paramètres de type Object (Action, Action<object>).

L’autre nouveautés très sympathique est la possibilité de paralléliser facilement ses boucles. Si on part des exemples suivants :

foreach (string filename in Directory.GetFiles(MyDirectory, "*"))
    Console.WriteLine(filename);

for (int i = 0; i < 200; i++)
{
    if (i % 2 == 1)
        Console.WriteLine(i + " ");
}

Il est possible d’exécuter les itérations en parallèle en remplacement le for et le foreach par Parallel.For et Parallel.Foreach.

Parallel.ForEach(Directory.GetFiles(MyDirectory, "*"), (filename) =>
{
    Console.WriteLine(filename);
});

Parallel.For(0, 200, (i) =>
{
    if (i % 2 == 1)
        Console.WriteLine(i + " ");
});

Et c’est tout !!! Le taskscheduler s’occupe de la répartition des opérations sur le processeur. On peut ainsi passer d’un code compliqué de copie de fichier multithreadée :

public void SpeedCopyFolder(DirectoryInfo source, DirectoryInfo target, bool overrideExisting)
{
    using (ManualResetEvent mre = new ManualResetEvent(false))
    {
        int threadCount = 0;
        foreach (FileInfo fi in source.GetFiles())
        {
            Interlocked.Increment(ref threadCount);
            // Create a thread for each file
            FileInfo file = new FileInfo(fi.FullName); // Created for the delegate scope
            ThreadPool.QueueUserWorkItem(delegate
            {
                if (File.Exists(Path.Combine(target.ToString(), file.Name)) && !overrideExisting)
                    return;
                fi.CopyTo(Path.Combine(target.ToString(), file.Name), overrideExisting);
                if (Interlocked.Decrement(ref threadCount) == 0) mre.Set();
            });
        }
        if (Interlocked.Decrement(ref threadCount) == 0) mre.Set();
        mre.WaitOne();
    }
}

à un code beaucoup plus simple :

public static void CopyFiles(string fromFolder, string toFolder)
{
    Parallel.ForEach<string>(Directory.EnumerateFiles(fromFolder, "*"), f =>
    {
        File.Copy(f, toFolder + @"\" + Path.GetFileName(f), true);
    });
}

  • Le namespace System.Collections.Concurrent

Ce namespace contient des collections utilisables dans les cas de multithreading. Ces collections utilisent une interface créé spécialement pour l’occasion : IProducerConsumerCollection<T> qui permet la manipulation de ces collections.

Les collections ainsi ajoutés :

Les collections classiques fonctionnent toujours avec les tasks (sur les exemples que j’ai pu essayer.). Je pense qu’il doit y avoir des différences de performances/d’utilisations possibles qui doivent indiquer quel type utiliser. Je publierais surement un post quand j’en saurais un peu plus sur le sujet.

  • Parallel LINQ

PLINQ est une technologie qui permet de paralléliser vos requêtes LINQ.

Prenons l’exemple suivant : On souhaite récupérer les fichiers dont la première lettre est un ‘a’ puis classer ce résultat selon la dernière lettre du nom du fichier. On aurait là requête LINQ suivante  :

Directory.GetFiles(MyDirectory, "*").Where((name) => name.First() == 'a').OrderBy((name) => name.Last());

Si l’on étudie un peu la façon dont la requête s’éxécute, LINQ va d’abord parcourir la liste des fichiers en recherche de ceux commençant par a puis il va les classer par ordre. Cela est logique pour un traitement mono-core. Toutefois, on pourrait imaginer faire le classement en parralèle du Where. Ainsi lorsque le Where trouve un élément commençant par un ‘a’, il est envoyé au Orderby (se trouvant dans un autre thread) qui réalise un classement en temps réel. Vous devez vous dire que cela doit être complexe à coder. Pourtant voici là façon de faire.

Directory.GetFiles(MyDirectory, "*").AsParallel().Where((name) => name.First() == 'a').OrderBy((name) => name.Last());

Il suffit de rajouter un AsParallel() afin que toutes les expressions suivantes s’exécutent “simultanément”. “C’est pas wonderful ?!?!”

  • C’est bien beau tout ça mais … et les performances ?

Sur un exemple qui est très parlant pour PLINQ (BabyNames disponible sur le training Kit VS 2010), j’obtiens les résultats suivants (sur une machine 4 cœurs avec une sélection du nombre de cœurs utilisés pour l’application).

    Nombre de cœurs LINQ (temps en secondes) PLINQ (Temps en secondes) Amélioration
    1 37,71 38,57 x 0.98
    2 37,46 20,68 x 1.81
    3 37,14 12,82 x 2.90
    4 37,36 10,60 x 3.53

Remarque : La raison pour laquelle on n’arrive pas à 4x plus de performance avant un quad core est tout simplement du au fait que l’OS plus d’autres applications tourne en arrière plan avec des pics imprévisibles. De plus, les mécanismes de synchronisation entre thread prend aussi un peu de la puissance de calculs.

Pour terminer, un petit graph qui fait plaisir :

pfx2

  • Conclusion

Cet technologie va surement réconcilier de nombreux développeurs avec la gestion des applications multithreadés. Toutefois, il est à noter que, dans certains cas, le parallélisme peut nuire au performance de l’application (car cela implique toujours en tâches de fond des techniques de synchronisation). A utiliser avec parcimonie et toujours en testant les performances avec et sans TPL.

Remarque : TPL est disponible en C++ aussi.

Note : Ce post a été fortement inspiré du post de Gal Ratner : http://galratner.com/blogs/net/archive/2010/04/24/a-quick-lap-around-net-4-0-s-parallel-features.aspx

25/02/2010

Erreur Visual Studio : “The following module was built either with optimizations enabled or without debug information”

Filed under: .NET, Débutant, Hors Catégorie, Visual Studio — Étiquettes : , , , , — sebastiencourtois @ 13:31

Un collègue est tombé sur ce problème ce matin en voulant débugger un service.

Debug

Remarque : Cette boite de dialogue est généralement accompagné d’un nom de dll/exe. Elle a été enlevé ici de la copie d’écran.

Apparemment Visual Studio n’arrive pas à rentrer en mode DEBUG. Dans ce cas là, plusieurs choses à vérifier tout de suite :

  1. Vérifier l’onglet Build du fichier csproj du projet concerné (indiqué par le nom de la dll).
    • Vérifier que votre configuration est bien sur “Debug”
    • Vérifier que la case “Optimize code” est décoché (même en Debug, on ne peut pas débugger du code optimisé).
    • Vérifier que le résultat de la compilation va bien dans le répertoire que vous souhaitez (Output Path)
    • Cliquer sur le bouton “Advanced” et vérifier que “Debug Info” est sur “Full”.

CsprojBuild

2. Dans le répertoire de sortie du projet, vérifier que la DLL est bien accompagné d’un fichier pdb du même nom. Ce fichier contient les symboles permettant le debug de l’assembly. Si ce n’est pas le cas, faites un “clean project” puis “Build Project”. Ces fichiers devraient apparaitre.

2bis. Si ce n’est toujours pas le cas,voir point 4.

3. Vous avez un fichier pdb dans votre répertoire de sortie mais pas dans le répertoire où est utilisé votre assembly. Un test rapide est de copier le pdb dans le répertoire où est utilisé l’assembly et lancer l’application (F5). Si cela fonctionne, passer au point 4 pour automatiser la copie.

4. Depuis Visual Studio, supprimer la référence de la dll incriminée des projets puis rajouter la de nouveau. Un petit Clean/Rebuild Solution devrait tout faire rentrer dans l’ordre.

Je ne sais pas exactement la raison de ce problème.Apparemment “sans raison”, Visual Studio conserve une ancienne version de la dll et/ou ne transfère pas les fichiers pdb. Dans le cas de mon collègue, le point 4 a permis la résolution du problème.

En espérant que ce post aidera des gens. Si quelqu’un à une explication sur la raison du non transfert des fichiers pdb, je suis intéressé.

11/03/2009

Erreur 404 lors d’un Debug d’un projet ASP.NET en utilisant “ASP.NET Development Server” sur localhost pour Vista

Filed under: Hors Catégorie, Intermediaire — Étiquettes : , , , , , , , , , — sebastiencourtois @ 12:10

Bon, le titre est un peu long pour un post aussi court mais il s’agit des mots clés que j’ai mis dans Google pour résoudre un bug qui m’empêchait de bosser depuis quelques temps (d’où le peu de post sur ce site récemment).

Lorsque je travaillais sur un projet ASP.NET (Silverlight ou autres), je me prenais systématiquement une page d’erreur 404 au lancement du débogage. J’étais sûr à 99.99 % que cela ne venait pas de mes projets car je les utilisait depuis plusieurs mois sans problème.

Après de longues recherches (car très peu de posts parlent de ce problème), j’ai trouvé le blog de Accidental Technologist et sur celui de Information for Technology qui indiquent que cela vient d’un bug/problème sous Vista avec les adresses IPv6 pour localhost.

La Solution :

Modifier le fichier hosts dans le répertoire C:\Windows\System32\drivers\etc.

Remplacer

::1             localhost

par

:::1             localhost  (si vous êtes en IPv6)

127.0.0.1             localhost  (si vous êtes en IPv4)

 

Cette solution m’a permis de visualiser ma page sous IE.

L’explication :

Je n’ai pas trouvé d’explication exacte quant à ce problème mais je vais vous donner ma reflexion :

en IPv4, l’adresse localhost est 127.0.0.1.

Avec l’arrivée de l’IPv6, on obtient l’adresse localhost suivante : 0:0:0:0:0:0:0:1

Or d’après la norme IpV6, on peut supprimer les 0 quand il y en a : 0:0:0:0:0:0:0:1 => :::::::1  (7 caractères ‘:’ et un caractère ‘1’)

Toujours d’après cette norme. Si plusieurs ‘:’ se suivent, on peut les remplacer par un seul au début et un seul à la fin donc  :::::::1 => ::1

Lorsque l’on tape dans IE, la chaine suivante : http://[::1]/ .On retombe bien sur la page localhost.

Deux questions me viennent donc à l’esprit :

1°) Pourquoi rajouter un ‘:’ dans le fichier host (Sachant que d’après la norme :  ::1 == :::1 == 0:0:0:0:0:0:0:1 et que ::1 est bien localhost dans la norme) ?

2°) Que s’est-il passé sur mon ordinateur pour que ce problème apparaisse alors que mes projets fonctionnaient correctement à l’origine (Problème détecté la première fois le 10/03/09) ?

Si vous arrivez à répondre à l’une de ces questions, n’hésitez pas à poster en commentaire :). Je continue à chercher de mon coté et je mettrais à jour ce post si je trouve.

EDIT 11/03/09 12h27 : Apparemment pas le seul dans ce cas, car j’ai reçu ce mail  il y a quelques minutes (venant un Microsoft Student Partner dont je vais taire le nom 🙂 ) :  “je voulais savoir si tu avais déjà eu des problèmes avec Cassini, parce que là il ne veut plus m’afficher aucune page que ce soit sur un site ASP.Net MVC, ou ASP.Net classique.”.

EDIT 11/03/09 15h00 : Il semble qu’une mise à jour de Windows Defender aurait modifier le fichier hosts entrainant des bugs sur les sites ‘localhost’

02/03/2009

Premier post de ce blog

Filed under: Hors Catégorie — Étiquettes : , , , , , , — sebastiencourtois @ 22:59

Bonjour à tous,

Je vais commencer par me présenter :

Je m’appelle Sébastien Courtois.

Je suis Consultant / Chef de projet .NET chez Winwise à Paris.Je fait partie du pôle RIDA (Rich Internet and Desktop Application). Pour résumer, je travaille régulièrement en Winforms, ASP.NET, Silverlight, WPF, ASP.NET MVC …

Afin de rendre ce blog unique, je vais essayer de publier un article/astuce par jour. Je ne sais pas si je tiendrais le rythme :).

Les articles et astuces seront principalement des cas pratiques tirés de ma propre expérience ou des expériences/questions d’autres personnes avec qui j’ai l’habitude de travailler (ils se reconnaitront surement assez vite). Ce ne seront souvent pas des exemples très poussés mais plus des petits problèmes quotidiens qui nous font perdre un temps précieux en projet.

En espérant que ce blog vous aidera et vous plaira. N’hésitez pas à m’envoyer des retours sur les erreurs ou les améliorations possibles (il y en aura surement :)).

Créez un site Web ou un blog gratuitement sur WordPress.com.

%d blogueurs aiment cette page :