C# - marc. ?· C# avancé Les exceptions • de nombreuses exceptions sont déjà gérées par le système…

  • Published on
    07-Feb-2019

  • View
    212

  • Download
    0

Transcript

C# .NET

Marc Chevaldonnmarc.chevaldonne@u-clermont1.frhttp://marc.chevaldonne.free.fr/ens_rech/Csharp_XML_GI_2010_2011.html

Anne scolaire 2010 - 2011

1

lundi 4 octobre 2010

mailto:marc.chevaldonne@u-clermont1.fr?subject=mailto:marc.chevaldonne@u-clermont1.fr?subject=http://marc.chevaldonne.free.fr/ens_rech/Csharp_XML_GI_2010_2011.htmlhttp://marc.chevaldonne.free.fr/ens_rech/Csharp_XML_GI_2010_2011.html

C# avancLes vnements

objectif : simplifier le pattern broadcaster/subscriber tout en apportant plus de scurit

le pattern broadcaster/subscriber avec les dlgus est dangereux car un subscriber peut modifier lcoute dun autre subscriber => solution : les vnements => tutoriel 1 : introduction aux vnements cf. exemple 70

il est conseill de suivre le pattern standard utilis dans la plateforme .NET et par tous les codeurs .NET (dignes de ce nom) => tutoriel 2 : standard event pattern cf. exemple 71

trs utiliss dans les interfaces graphiques fentres cf. exemple 72

2

lundi 4 octobre 2010

C# avancLes exceptions

de nombreuses exceptions sont dj gres par le systme index out of range null reference type ... cf. exemple 73

rappel : on peut en viter de nombreuses laide de TryParse la place de Parse cf. exemple 74

3

lundi 4 octobre 2010

C# avancLes exceptions

les instructions : cf. exemple 75 try :

si le code dans le bloc try gnre une exception => bloc catch sinon on continue

catch : indique quel type dexception il faut trater

finally : toujours excut (aprs le try (et les catch), exception ou non)

rethrow dexceptions (cf. exemple 76)

on peut crer sa propre classe dexception (cf. exemple 77)

4

lundi 4 octobre 2010

C# avancDirectives prprocesseur

fournir des informations additionnelles au compilateur propos de rgions dans le code

les plus connues sont les directives conditionnelles pour inclure (exclure) des rgions de code dans (de) la compilation

VisualStudio permet dentrer les symboles de compilation conditionnelle dans les proprits de projet

#define DEBUGclass UneClasse{ int a; void UneMthode() { #if DEBUG Console.WriteLine(Test : a = {0}, a); #endif } ...}

5

lundi 4 octobre 2010

C# avancDirectives prprocesseur

Quelques directives prprocesseur

6

#define symbole dfinit le symbole

#undef symbole dfait la dfinition du symbole

#if symbole [operator symbole2]...test entre symbole et symbole2

oprateurs : == != && ||suivi ventuellement de #else #elif #endif

#endif termine une directive conditionnelle

#else code excut aprs un #endif

#elif symbole [operator symbole2]... combine #else et #if branches

#region nom marque le dbut dune rgion

#end nom marque la fin dune rgion

lundi 4 octobre 2010

C# avancDirectives prprocesseur - Attribut conditionnel

Lattribut Conditional indique au compilateur dignorer tous les appels dune classe ou dune mthode si le symbole nest pas dfini

le compilateur entoure implicitement les appels de la classe ou de la mthode avec des directives #if

[Conditional (TEST)]static void MthodeDeDebug(string message_debug){ ...}

cf. exemple 78

7

lundi 4 octobre 2010

C# avancclasses Debug et Trace

Debug et Trace sont des classes statiques (trs similaires) qui permettent la gestion de mthodes classiques pour le debug : logging assertion

Debug est utilise en mode ... debug toutes ses mthodes sont dfinies avec lattribut [Conditional(DEBUG)]

Trace est utilise en modes debug et release toutes ses mthodes sont dfinies avec lattribut [Conditional(TRACE)]

Par dfaut, VisualStudio dfinit : les symboles DEBUG et TRACE en mode debug le symbole TRACE en mode release

8

lundi 4 octobre 2010

C# avancclasses Debug et Trace

mthodes de Debug et Trace (cf. exemple 78) Write WriteLine WriteIf

mthodes de Trace (cf. exemple 78) TraceInformation TraceWarning TraceError

mthodes de Debug et Trace pour les assertions (cf. exemple 78) Fail Assert

TraceListener (cf. exemple 78) fichier XML Console...

9

lundi 4 octobre 2010

C# avancbien debugger...

Quelques conseils pour amliorer le debug :

+ rcrire ToString + utiliser lattribut conditionnel DEBUG : ne faire des affichages Console qu

travers une mthode avec lattribut conditionnel DEBUG ou travers la classe Trace (+ TraceListener)

+ utiliser les classes Debug et Trace (en particulier Write, WriteIf, Assert et Fail)

- viter dcrire soi-mme les directives prprocesseurs #if... --- ne jamais faire daffichage Console depuis ses classes en dehors des

rgles prcdentes !!!

10

lundi 4 octobre 2010

Disposal et Ramasse-miettesGarbage Collector : comment a marche ?

Le Garbage Collector (GC) contrle la mmoire manage pour vous (memory leaks, pointeurs, ...)

Vous (les dveloppeurs de classes et les clients de ces classes) tes responsables du nettoyage des ressources non manages : fichiers connections aux bases de donnes COM objects certains objets graphiques ...

Le GC dtecte si un objet est accessible en traversant larbre de lapplication depuis la racine (dtecte ainsi les rfrences circulaires et les relations complexes entre objets)

Tout ce qui ne peut pas tre atteint depuis lapplication est mort et sera libr par le GC

11

lundi 4 octobre 2010

Disposal et Ramasse-miettesGarbage Collector : comment a marche ?

Le GC fonctionne dans un thread spcifique

Le GC rarrange le tas chaque passage pour noccuper que des blocs mmoire contigus

2 outils pour aider le dveloppeur librer la mmoire non manage : les finaliseurs :

un mcanisme assurant quun objet pourra toujours librer les ressources non manages

inconvnient : cot en termes de performance linterface IDisposable :

mthode plus lgre pour librer la mmoire non manage et plus performante

inconvnient : le client doit penser lappeler (donc pas sr 100%)

12

lundi 4 octobre 2010

Disposal et Ramasse-miettesGarbage Collector : comment a marche ?

Les finaliseurs sont appels par le GC aprs avoir t mis la poubelle environ la mme syntaxe que les destructeurs en C++ cest le moyen le plus sr de nettoyer la mmoire non manage, mais : on ne sait pas quand... contrairement au C++ (ctor / destor) quand le GC veut nettoyer un objet et dcouvre quil a un finaliseur, il ne

libre pas tout de suite : le GC place tous les objets qui ont un finaliseur dans une queue les finaliseurs sont appels dans un autre thread et pendant ce temps le

GC continue son travaille cest seulement au cycle suivant que le GC libre donc ces objets ayant

un finaliseur (qui restent donc plus longtemps)

13

lundi 4 octobre 2010

Disposal et Ramasse-miettesGarbage Collector : comment a marche ?

En fait, les objets ayant un finaliseur ne restent pas quun cycle de plus... Le GC utilise un systme de gnrations :

gnration 0 : objets crs depuis la dernire opration du GC gnration 1 : objets ayant survcu une opration du GC gnration 2 : objets ayant survcu deux oprations ou plus du GC

permet de grer diffremment les variables locales des rfrences plus durables : les variables locales sont gnralement de gnration 0 les membres et les variables globales entrent rapidement en gnration 1,

et ventuellement en gnration 2

Pour amliorer ses performances : le GC examine chaque cycle les objets de gnration 0, 1 cycle sur 10, il examine les objets de gnration 0 ou 1, 1 cycle sur 100, il examine tous les objets

Un objet ayant un finaliseur peut donc rester 9 cycles de plus quun objet sans finaliseur, ou pire : 90 cycles de plus !

14

lundi 4 octobre 2010

Disposal et Ramasse-miettesGarbage Collector : comment a marche ?

Les finaliseurs restent indispensables car ils sont le seul moyen sr de librer la mmoire non manage...

... mais la solution de limplmentation de IDisposable peut permettre de navoir recours aux finaliseurs que dans des cas prcis, et dviter le cot en performances

15

lundi 4 octobre 2010

Disposal et Ramasse-miettesGarbage Collector : comment a marche ?

Linterface IDisposable ne possde quune mthode : void Dispose( ) Lappel de Dispose libre les ressources manages et non manages puis

prviens le GC quil nest pas ncessaire dappeler le finaliseur En consquence :

si le client appelle Dispose, les ressources sont libres plus rapidement car le finaliseur nest pas utilis

si le client nappelle pas Dispose, les ressources seront libres (mais beaucoup plus tard) lors de lappel du finaliseur

Conseils : si vous tes client, appelez Dispose sur toutes les classes implmentant

IDisposable lorsque vous navez plus besoin des instances si vous tes dveloppeur dune classe avec des ressources non

manages, implmentez linterface IDisposable

16

lundi 4 octobre 2010

Disposal et Ramasse-miettesGarbage Collector : comment a marche ?

Comment utiliser une classe implmentant IDisposable ?

Lappel de la mthode Dispose permet de librer les ressources non manages, mais sil y a une mthode entre linstanciation de la classe et lappel de Dispose qui lance une exception, Dispose ne sera pas appele et cest donc le finaliseur qui le sera

=> mauvaise mthode

Linstanciation et lutilisation de la classe implmentant IDisposable se fait dans un bloc try, et lappel de Dispose dans le bloc finally associ

=> Dispose est ainsi toujours appele => bonne mthode

Puisque cest une bonne mthode, .NET propose lutilisation de linstance de la classe implmentant IDisposable dans un bloc using

=> quivalent try/finally + Dispose => sauf quon na mme pas besoin dappeler Dispose (automatique)

17

lundi 4 octobre 2010

Disposal et Ramasse-miettesGarbage Collector : comment a marche ?

Comment implmenter correctement une classe avec des ressources non manages ?

Il existe un pattern quil est prfrable de respecter : classe de basepublic class LaClasseDeBase : IDisposable{ private bool disposed = false; public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool isDisposing) { if(disposed) { return; } if(isDisposing) { /* librer les ressources manages ici*/ } //librer les ressources non manages ici disposed = true; }}

18

lundi 4 octobre 2010

Disposal et Ramasse-miettesGarbage Collector : comment a marche ?

Comment implmenter correctement une classe avec des ressources non manages ?

Il existe un pattern quil est prfrable de respecter : classe fillepublic class LaClasseDrive : LaClasseDeBase{ private bool disposedClasseDrive = false;

protected virtual void Dispose(bool isDisposing) { if(disp disposedClasseDrive osed) { return; } if(isDisposing) { /* librer les ressources manages ici*/ } //librer les ressources non manages ici

//on laisse le soin la classe de base dappeler //GC.SuppressFinalizer base.Dispose(isDisposing);

disposed = true; }} 19

lundi 4 octobre 2010

Recommended

View more >