Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

FxCop και IDisposable implementation warning

Îåêßíçóå áðü ôï ìÝëïò entrodus. Τελευταία δημοσίευση από το μέλος KelMan στις 11-04-2007, 12:12. Υπάρχουν 4 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  10-04-2007, 16:40 28440

    FxCop και IDisposable implementation warning

    Αφού με χαρά εντόπισα αυτό το απίστευτο εργαλειάκι (fxCop) που θα με βοηθήσει να κατανοήσω και να φτιάξω καλύτερα τον κώδικα μου, το έτρεξα και έπεσα πάνω σε αυτό το warning:

    "Types that declare disposable members should also implement
    IDisposable. If the type does not own any unmanaged
    resources, do not implement a finalizer on it."
    Help: http://www.gotdotnet.com/team/fxcop/docs/rules.aspx?version=1.35&url=/Design/TypesThatOwnDisposableFieldsShouldBeDisposable.html


    (Στον κώδικα  μου, μου χτυπάνε κάποια DataTables που έχω δηλώσει σε κάποιες κλάσεις. )

    Πρέπει όντως να κάνω implement το IDisposable? Έχει δηλαδή unmanaged resources το DataTable (?!?) και αν ναι, πως κλείνουν?
    Στο παράδειγμα του fxCop έχει FileStream και απλώς τα κάνει Close.

    Εντομεταξύ, το fxCop γενικώς είναι "σωστό" σαν εργαλείο?
    Προσπάθησα να αντιγράψω τη λογική αυτή με τα DataTables σε ένα μικρότερο project για να κάνω τις δοκιμές μου, αλλά το fxCop δεν μου χτύπησε warning για dispose.
    The Bible was written by the same people
    who said the Earth was flat.
    Δημοσίευση στην κατηγορία: ,
  •  10-04-2007, 17:19 28445 σε απάντηση της 28440

    Απ: FxCop και IDisposable implementation warning

    Γενικά, το FxCop είναι φοβερό εργαλείο. Ειδικά στον έλεγχο για τον σωστό ορισμό του IDisposable κυριολεκτικά καταλαβαίνει τί κάνει ο κώδικας σου και σου βρίσκει τα λάθη. Το περίεργο είναι ότι μερικά από αυτά τα λάθη τα βρίσκει στον generated κώδικα των typed datases, services κλπ!

    Γενικά, η κλάση Dispose χρησιμεύει για να καθαρίζει είτε unmanaged είτε ακριβά resources, όπως ένα connection, ένα stream, μεγάλους πίνακες κλπ, τα οποία θέλεις να ελέγχεις πότε θα ελευθερωθούν. Επειδή όμως άλλο το dispose λόγω finalization και άλλο επειδή κάλεσες την dispose, χρειάζεσαι δύο overloads της dispose. Η μία παίρνει σαν παράμετρο το isDisposing που ειδοποιεί για το αν το dispose γίνεται λόγω finalization ή επειδή κάλεσες την Dispose. Η διαφορά είναι ότι όταν γίνεται finalization δεν ξέρεις αν τα πεδία της κλάσης έχουν υπαρκτά αντικείμενα ή έχουν ήδη γίνει finalize! Μπορεί π.χ. να πας εσύ να κάνεις dispose ένα stream και αυτό να έχει ήδη γίνει disposed. Γι αυτό, η Dispose(bool) έχει ένα if το οποίο καλεί την Dispose του κάθε πεδίου αν έχει τιμή true. Για τα unmanaged resources δεν ισχύει αυτό, και πάντα τα κλείνεις/σβήνεις έξω από το if. Πέρα από αυτό, η απλή Dispose() καλεί την Dispose(true) ενώ ο finalizer την Dispose(false).

    Άλλη σημαντική λεπτομέρεια, είναι ότι η Dispose(bool) πρέπει να είναι protected virtual για να μπορούν οι child κλάσεις να κάνουν override και να προσθέσουν τον δικό τους κώδικα για dispose. Τελευταία λεπτομέρεια, είναι ότι τελειώνοντας η Dispose() πρέπει να καλέσει την GC.SuppressFinalize, για να ειδοποιήσει το .NET ότι έχει ήδη γίνει το dispose, και να μην ξανακαλέσει τον finalizer. Τέλος, για να αποφευχθούν προβλήματα του στυλ καλώ δύο φορές την Dispose, η Dispose(bool) ελέγχει ένα πεδίο, το disposed ή _disposed ή όπως θέλεις να το πεις, σε true και τερματίζει αμέσως αν το βρει true. Αλλιώς, όταν τελειώσει το θέτει true.

    Και το FxCop τα ελέγχει όλα αυτά!

    Ο λόγος τώρα που σου βγάζει warnings σε κάποια generated datatables, services κλπ και δεν σου το βγάζει σε απλά datatables είναι ότι τα typed datatables ή τα services είναι ουσιαστικά απλές κλάσεις. Επειδή συνήθως αυτές οι κλάσεις δεν περιέχουν επιπλέον πεδία, ο generated κώδικας για το dispose δεν υλοποιεί όλες τις λεπτομέρεις. Το FxCop όμως δεν μπορεί να ξέρει αν η κλάση περιέχει πεδία που κρατάνε unmanaged ή ακριβά resources, γι αυτό σε ειδοποιεί. Μπορείς να αγνοήσεις αυτή την ειδοποίηση ή να τροποποιήσεις την Dispose των Datatable για να μην γκρινιάζει το FxCop.

    Είχα διαβάσει και εγώ αρκετά πράγματα για το πως φτιάχνει κανείς ένα σωστό Dispose, αλλά το κατάλαβα πραγματικά όταν άρχισα να διορθώνω τα warnings του FxCop. Δεν είναι υπερβολή να πω ότι το σωστό IDisposable το έμαθα από το FxCop!


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  11-04-2007, 10:53 28512 σε απάντηση της 28445

    Απ: FxCop και IDisposable implementation warning

    Ευχαριστώ για την απάντηση-δοκίμιο.
    Είναι λίγο μπερδεμένα ακόμα τα πράγματα...

    Για αρχή μάλλον βλέπω να αγνοώ τα μηνύματα, θα διαβάσω καμιά 30ρια φορές ακόμα την απάντηση σου... ψάχνω και κανα αρθράκι... και σιγά σιγά θα βγάλω την άκρη.


    The Bible was written by the same people
    who said the Earth was flat.
  •  11-04-2007, 11:16 28516 σε απάντηση της 28512

    Απ: FxCop και IDisposable implementation warning

    Τα warnings που αφορούν typed datasets, typed datatables μπορείς να τα αγνοήσεις, εκτός κι αν έχεις πειράξει τον κώδικα τους και έχεις προσθέσει νέα πεδία. Τα warnings που αφορούν δικές σου κλάσεις θα πρέπει να τα διορθώσεις.

    Θα βρεις ένα καλό άρθρο για το IDisposable στο http://www.codeproject.com/csharp/DestructorsInCs.asp και ένα template για τη σωστή υλοποίηση του στο http://www.idesign.net/idesign/DesktopDefault.aspx?tabindex=-1&tabid=19&download=40 . Ο Juval Lowy, ο οποίος δουλεύει στην IDesign, έχει γράψει ένα πολύ καλό βιβλίο, το ".NET Components" της O' Reilly στο οποίο περιγράφει σε μεγάλη λεπτομέρεια το πως και το γιατί του IDisposeable.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  11-04-2007, 12:12 28528 σε απάντηση της 28516

    Απ: FxCop και IDisposable implementation warning

    Επίσης, στο site της IDesign έχει ένα πολύ ωραίο οδηγό Coding Standards Guidelines & Best Practices

     


    Vir prudens non contra ventum mingit
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems