Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Ξαφνικά βρέθηκα "περικυκλωμένος" από αμφιβολίες για το αν έχω κατανοήσει σωστά τον κύκλο ζωής των αντικειμένων στο .NET.

 

Θέλω να ξεκινήσω με αυτό:

 

Διαβάζω εδώ

 

If disposable object x contains or "wraps" or "possesses" disposable object y, x's Dispose method automatically calls y's Dispose method - unless instructed otherwise.

 

Κάνω λοιπόν το εξής.

 

>
class T1 : IDisposable
{
 public void Dispose()
 {
	 Console.WriteLine("T1 Disposed");
 }
}
class T2 : IDisposable
{
 private T1 ts = new T1();
 public void Dispose()
 {
	 Console.WriteLine("T2 Disposed");
 }
}
class Program
{
 static void Main(string[] args)
 {
	 using (var d = new T2())
	 {
	 }
 }
}

 

Και η έξοδος που έχω είναι

 

T2 Disposed

 

Και τίποτε άλλο.

 

Τι γίνεται;...

 

 

Και γενικότερα (από κει που μου ξεκίνησε η απορία).

Έστω ότι έχω μια φόρμα windows forms.

 

Και μέσω ενός κουμπιού ανοίγει με ShowDialog μία άλλη φόρμα που έχει 1 DataTable εσωτερικά της (το οποίο είναι disposable) (δε μιλώ για τα gui components).

 

Όταν θα κλείσει ο χρήστης τη φόρμα αυτή, το table θα γίνει dispose ή όχι;

 

Και εάν όχι, κάθε φορά που θα ανοίγω το dialog αυτό, θα κρέμονται στη μνήμη DataTables;

 

Ευχαριστώ εκ των προτέρων.

  • Απαντ. 31
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Δημοσ.

Θα γίνει dispose κανονικά μόλις το συλλέξει ο garbage collector.

Αυτό είναι το νόημα του IDisposable. Όταν χειρίζεσαι unsafe code το κάνεις IDisposable για να απελευθερώνεις όση μνήμη δέσμευσες. Αν δεν καλέσεις μόνος σου την Dispose() την καλεί αυτόματα ο Garbage Collector.

Δημοσ.

Ποτέ δεν καλεί τη Dispose() o Garbage Collector.

Στο παράδειγμα με Form o designer έχει φτιάξει αυτόν τον κώδικα, (Form1.Designer.cs)

 

>
protected override void Dispose(bool disposing)
 {
	 if(disposing && (components != null))
	 {
		 components.Dispose();
	 }
	 base.Dispose(disposing);
 }

που καλείται όταν κλείνει η Φορμα.

 

Αν δεν έχει προστεθεί στα components to DataTable (π.χ. είναι local σε μια συνάρτηση) δε θα γίνει Dispose())

 

If disposable object x contains or "wraps" or "possesses" disposable object y, x's Dispose method automatically calls y's Dispose method - unless instructed otherwise.

Αυτοί είναι κανόνες που σέβεται το .ΝΕΤ και συνιστώνται γενικά.

Απλή συνάρτηση σαν όλες της άλλες είναι.

Δημοσ.

Ποτέ δεν καλεί τη Dispose() o Garbage Collector.

Αν δεν έχει προστεθεί στα components to DataTable (π.χ. είναι local σε μια συνάρτηση) δε θα γίνει Dispose())

...

Αυτοί είναι κανόνες που σέβεται το .ΝΕΤ και συνιστώνται γενικά.

Απλή συνάρτηση σαν όλες της άλλες είναι.

 

Δε μιλάω για το DataGridView που είναι (visual) component της φόρμας.

Μιλάω για το DataTable που είναι απλά ένα disposable αντικείμενο (και είναι παράδειγμα).

 

Και η απορία μου είναι οτι αν ισχύει αυτό που έχω στα quote τότε όταν καλείται η dispose του Τ2 θα πρέπει να καλείται και η dispose του πεδίου T1 που περιέχει (σύμφωνα με τον κανόνα που παρέθεσα) αλλά δεν βλέπω να συμβαίνει.

 

Άρα θα πρέπει κάθε disposable αντικείμενο το οποίο δεν είναι μέσα σε ενα using να καλείτε με το χέρι το dispose του κάποια στιγμή οπωσδήποτε.

 

 

Άρα ακόμα και αν υπάρχουν 2 - 3 DataTable (που μπορεί να χρησιμοποιούνται σαν datasource για κάποια DataGridView) θα πρέπει έστω στο on_closed event να τα κάνει κανείς dispose διαφορετικά "κρέμονται" στη μνήμη;

 

Αυτή είναι η απορία μου.

 

Κοινώς είναι λάθος αυτό το που παρέθεσα από το βιβλίο;

Δημοσ.

Στην C# δεν εχεις την εννοια του destructor

 

Σύμφωνοι (αν και υπάρχει αλλά δεν είναι απαραίτητος αν έχεις απλά .net αντικείμενα στην class). Αλλά δεν μιλάω για destructor. Για τα disposable αντικείμενα μιλάω. Και για το αν και καταπόσο ισχύει αυτό που παρέθεσα στο quote.

Δημοσ.

Και η απορία μου είναι οτι αν ισχύει αυτό που έχω στα quote τότε όταν καλείτε η dispose του Τ2 θα πρέπει να καλείται και η dispose του πεδίου T1 που περιέχει (σύμφωνα με τον κανόνα που παρέθεσα) αλλά δεν βλέπω να συμβαίνει.

 

Αυτό δεν έγινε διότι δεν σεβαστικές τους κανόνες στα quote.

 

Εσύ έπρεπε μέσα στο Dispose(){ } της Τ2 να προσθέσεις ts.Dispose().

 

Η Dispose() δεν είναι destructor, ούτε καλείται από μόνη της.

Δημοσ.

Σύμφωνοι (αν και υπάρχει αλλά δεν είναι απαραίτητος αν έχεις απλά .net αντικείμενα στην class). Αλλά δεν μιλάω για destructor. Για τα disposable αντικείμενα μιλάω. Και για το αν και καταπόσο ισχύει αυτό που παρέθεσα στο quote.

Ε τοτε γιατι να υπαρχει αυτη η συμπεριφορα που λες; το dispose ειναι ενα interface που που καλειται σε try και using τιποτα αλλο

Δημοσ.

Στην C# δεν εχεις την εννοια του destructor

 

Βεβαίως και έχει

>
class MyClass
   {
    ~MyClass()
    {
	    Console.WriteLine("destructor");
    }
   }
   static class Program
   {
    static void Main()
    {
	    MyClass c = new MyClass();
    }
   }

Δημοσ.

Αυτό δεν έγινε διότι δεν σεβαστικές τους κανόνες στα quote.

 

Εσύ έπρεπε μέσα στο Dispose(){ } της Τ2 να προσθέσεις ts.Dispose().

 

Η Dispose() δεν είναι destructor, ούτε καλείται από μόνη της.

 

Να το δεχτώ και έτσι πρέπει να είναι. Αλλά γιατί λέει

 

x's Dispose method automatically calls y's Dispose method

 

αν εννοεί οτι πρέπει να το γράψεις εσύ;

Δημοσ.

Να το δεχτώ και έτσι πρέπει να είναι. Αλλά γιατί λέει

 

 

 

αν εννοεί οτι πρέπει να το γράψεις εσύ;

 

Δες msdn

Δημοσ.

Να το δεχτώ και έτσι πρέπει να είναι. Αλλά γιατί λέει

 

 

 

αν εννοεί οτι πρέπει να το γράψεις εσύ;

"The Framework follows a set of de facto rules" ... λέει.

Δημοσ.

Ε τοτε γιατι να υπαρχει αυτη η συμπεριφορα που λες; το dispose ειναι ενα interface που που καλειται σε try και using τιποτα αλλο

Μα η απορία μου είναι στο αν ισχύει το quote που λέει ότι καλείται αυτόματα αν στο dispose ενός disposable αντικειμένου που περιέχει ένα άλλο.

 

-

 

Άρα αν έχεις μια class που περιέχει κάποια DIsposable objects θα πρέπει στον finalizer (destructor) να καλέσεις και το dispose αυτών των disposabe objects ώστε οτα το μαζέψει ο garbage collector να κληθεί και το dispose αυτών.

 

 

Αντίστοιχα στη φόρμα στο on_close ή κάπου παρόμοια πρέπει να κάνεις το ίδιο αν έχεις προσθέσει disposable αντικείμενα.

 

Πάντως θέλω να επιμείνω στην ερώτηση.

 

Για κάθε DataTable (επαναλαμβάνω δε μιλάω για το visual component DataGridView) που μπορείς να φτιάξεις σε μία φόρμα, πρέπει να καλείται το Dispose χειροκίνητα;

 

Και ΑΝ ναι πρέπει να γίνουν dispose και όλα τα DataColumn s ξεχωριστά;

 

 

Υ.Γ.

Πάντως για να δείτε γιατί μπερδεύομαι στο msdn εδώ κάτω κάτω εκεί που λέει Dispose vs. Close Method Usage (άσχετο με την απορία μου) λέει

... and standard .NET Framework garbage collection calls the Dispose method to free any resources associated with the object from memory....

Δημοσ.

Μα η απορία μου είναι στο αν ισχύει το quote που λέει ότι καλείται αυτόματα αν στο dispose ενός disposable αντικειμένου που περιέχει ένα άλλο.

 

 

Οχι βεβαια!!!! Φαντασου να εχεις ενα resource στην main και αυτο να το περνας σε μια φορμα (απλο reference). Τοτε οταν κλεισεις την φορμα το resource θα απελευθερωθει, κατι που σιγουρα δεν θελεις εφοσον ειναι reference

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...