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

 

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

Singleton Form

Îåêßíçóå áðü ôï ìÝëïò infoCENTER. Τελευταία δημοσίευση από το μέλος ToyMaker στις 24-02-2006, 12:58. Υπάρχουν 24 απαντήσεις.
Σελίδα 1 από 2 (25 εγγραφές)   1 2 >
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  31-01-2006, 03:25 9045

    Singleton Form

    Το πρόβλημα είναι το εξής.

    Έχω μία φόρμα την οποία ανάλογα με το κάλεσμα που τις κάνω θέλω να φορτώνεται σε πολλά instances αλλά και ως singleton. Φτιάχνω λοιπόν την κεντρική φόρμα βάζω τα κουμπιά μου και πατάω π.χ "Εμφάνιση λίστας πελατών". Ο κώδικας για αυτό το κουμπί είναι ο εξής.

    Dim fCustomersList as New CustomersGridViewForm

    fCustomersList.MdiParent=Me

    fCustomersList.Show

    Με το παραπάνω ήμαστε εντάξει. Όσες φορές και αν πατήσω το κουμπί μου φορτώνει νέο instance της φόρμας. Πάμε παρακάτω τώρα. Στην εφαρμογή μου δεν θέλω να φορτώνεται κάθε φορά νέο instance. Αλλά να φέρνει πάντα το ένα που έχει φορτωθεί και αν όχι να δημιουργήσει ένα εκείνη την στιγμή. Επίσης όσα μελλοντικά καλέσματα γίνονται στον κώδικά μου να μην δημιουργειτε πάλι νέο Instance αλλά να φέρνει αυτό. Δηλαδή αν ξαναπατήσω πάλι το κουμπί "Εμφάνιση λίστας πελατών" να μην δημιουργήσει ξανά την φόρμα. Δείτε τον κώδικα και ελπίζω να καταλάβεται. Πάμε λοιπόν...

    Στην φόρμα CustomersGridViewForm γράφω το εξής :

    Public Class CustomerGridViewForm

    Private Shared mInstance As CustomerGridViewForm

    Public Shared Function SingletonLoad() As CustomerGridViewForm

    If mInstance Is Nothing Then mInstance = New CustomerGridViewForm

    Return mInstance

    End Function

    End Class

    Μετά από αυτό στο Event Click του Button γράφω τον εξής κώδικα:

    Dim fCustomersList as CustomersGridViewForm

    fCustomersList=CustomersGridViewForm.SingletonLoad

    Ο παραπάνω κώδικας τρέχει κανονικά στο πρώτο πάτημα του κουμπιού. Κλείνω την φόρμα και την κάνω dispose. Ξαναπατάω το κουμπί. Και εκεί παίρνω το εξής μήνυμα "Cannot access a disposed object". Δεν μπορώ να καταλάβω που είναι το πρόβλημα...

  •  31-01-2006, 07:38 9048 σε απάντηση της 9045

    Απ: Singleton Form

    Ρίξε μια ματιά εδώ http://www.dotnetzone.gr/cs/forums/2708/ShowPost.aspx που είχαμε ξανακουβεντιάσει το θέμα. Επίσης εδώ http://www.codeproject.com/vb/net/Simple_Singleton_Forms.asp αλλά και εδώ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconProgrammingEssentialsForGarbageCollection.asp για γενικότερες πληροφορίες περί του πως δουλεύει το Garbage Collection.


    Vir prudens non contra ventum mingit
  •  06-02-2006, 15:00 9301 σε απάντηση της 9045

    Απ: Singleton Form

    Χμμμ.... διάβασα τα links σου και μπορώ να πω ότι το δεύτερο έλυσε το πρόβλημα αλλά, δημιύργησε μία μεγάλη απορία που μέχρι τώρα δεν έτυχε να πέσω επάνω και ούτε και τα βιβλία ξεκαθαρίζουν κριβώς αυτό το θέμα ή αφήνουν θολές κάποιες λεπτομέρειες.
    Όταν φτιάχνεις μία μεταβλητή μέσα σε μία Class και "καταστρέψεις" αυτή την class τότε η class αυτή παραμένει στην μνήμη μέχρι ο GC να αναλάβει και να την σβύσει και απο εκεί. Για την εφαρμογή όμως το instance αυτό της classes είναι κατεστραμμένο. Δεν την ενδιαφέρει τι γίνεται στην μνήμη. Άρα με το dispose πάει το συγκεκριμένο instance της class για την εφαρμογή. Τότε γιατί θα πρέπει να θέσω mInstance=Nothing ????

    Αναρωτιέμαι....
  •  06-02-2006, 15:26 9305 σε απάντηση της 9301

    Απ: Singleton Form

    Αν κατάλαβα καλά την ερώτηση και χωρίς να έχω δει τον κώδικα στον οποίο αναφέρεσαι, υποθέτω ότι κάνει mInstance=Nothing για να δηλώσει ότι το object είναι διαθέσιμο για GC όσο το δυνατόν νωρίτερα...


    Vir prudens non contra ventum mingit
  •  06-02-2006, 16:35 9309 σε απάντηση της 9305

    Απ: Singleton Form

    Μα το mInstance είναι μεταβλητή που έχει δηλωθεί μέσα στην Class. Οπότε για να κάνεις την class dispose θα πρέπει λογικά να καταστρέφονται και οι μεταβλητές άσχετα αν ο GC δεν τα έχει καθαρίσει ακόμα από την μνήμη. Από την μεριά της εφαρμογής το συγκεκριμένο instance έχει φύγει. Και όμως πάει στο dispose της class και βάζει mInstance=Nothing. Δεν ξέρω αν καταλαβαίνεις το σημείο που με προβληματίζει.

    Θα μου επι τώρα κάποιος ότι η mInstance είναι shared. Σωστά αλλά δεν κρατάει μία αριθμητική ή αλφαριθμητική τιμή αλλά το instance της εφαρμογής η οποία με το dispose γίνεται Nothing. Άλλωστε αυτό ήταν και ένα από τα προβλήματα που είχαμε με τα DLL και υποτίθεται ότι ο GC ήρθε να το λύσει. Και το μήνυμα λάθους το λέει ξεκάθαρα "cannot access a disposed object" Άρα η mInstance δείχνει ακόμα σε αυτήν την περιοχή μνήμης; Υποτίθεταο ότι το .Net θα ερχόταν εδ'ω και θα έβαζε μόνο του mInstance=Nothing αντί να έχω αδέσποτους pointers. Το παραπάνω πιο πολύ σε unmanaged με παραπέμπει παρά σε managed συμπεριφορά.

  •  06-02-2006, 16:44 9310 σε απάντηση της 9309

    Απ: Singleton Form

    Να μιλήσουμε πάνω στον συγκεκριμένο κώδικα; Αναφέρεσαι στο άρθρο του CodeProject;
    Vir prudens non contra ventum mingit
  •  06-02-2006, 16:54 9311 σε απάντηση της 9310

    Απ: Singleton Form

    Ναι. Για αυτό πρόκειται.
  •  06-02-2006, 17:38 9313 σε απάντηση της 9301

    Απ: Singleton Form

    Η Dispose δεν καλείται αυτόματα από τον garbage collector. Είναι μια μέθοδος η οποία κατά σύμβαση καλείται όταν θέλουμε να ελευθερωθούν τα resources που κρατάει ένα instance αμέσως. Η δουλειά του είναι να καλέσει τις μεθόδους dispose σε όσα άλλα αντικείμενα περιέχει το instance και μετά να ελευθερώσει όσα resources ελέγχει το ίδιο το instance. Η μέθοδος αυτή καλείται είτε με το χέρι, είτε μέσα από άλλη Dispose είτε από την Finalize.

    Όλα αυτά είναι κατά σύμβαση. Ο Garbage Collector καλεί αυτόματα τη Finalize, όχι την Dispose. Η Finalize συνήθως καλεί την dispose γιατί πρέπει και οι δύο να εκτελέσουν τον ίδιο κώδικα.

    Συνεπώς, το mInstance=Nothing δεν είναι πλεονασμός, καθώς ελευθερώνει το resource του την ώρα που καλείται η Dispose, και όχι όταν θα κληθεί η Finalize, η οποία μπορεί και να κληθεί μετά από αρκετά λεπτά.
    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  06-02-2006, 18:08 9314 σε απάντηση της 9313

    Απ: Singleton Form

    Νομίζω ότι δεν κατάλαβες το σκεπτικό μου και την απορία κατά συνέπεια. Συμφωνώ σε όσα λες για τον GC.

    Απο εκεί και πέρα όμως όταν κάνω dispose από την μεριά της εφαρμογής είναι σαν να λέω τελείωσα με αυτό το instance. Άρα θα έπρεπε το .Net ΜΟΝΟ του να βρει ποια άλλα references έχουν γίνει σε αυτό το instance και να τα θέσει Nothing. Αντί να υπάρχουν άστοχοι όπως γράφω pointers. Από εκεί και πέρα δεν το κάνει. Περιμένει απο εμάς να το κάνει και να γράψουμε mInstance=Nothing.

    Όσο για τον GC ας κανονίσει αυτός πότε θα καθαρίσει την μνήμη.

    Κάποια στιγμή θα το κάνει, τότε η mInstance τι τιμή θα έχει; Που θα δείχνει; Τότε θα τεθεί σε Nothing; Ή θα δείχνει σε μία περιοχή μνήμης χωρίς δεδομένα;

    Πάντως η απορία μου δεν είχε να κάνει με την Dispose και τον GC. Έτυχε απλά ο τύπος στο παράδειγμα να το βάλει μέσα στην dispose. Θα μπορούσε να ήταν αλλού.
  •  06-02-2006, 18:15 9315 σε απάντηση της 9045

    Απ: Singleton Form

    Μπορείς αν θέλεις να αναγκάσεις τον GC να κάνει garbage collection, αλλά κατά κανόνα καλό είναι να το αποφεύγεις, καθώς δημιουργείς προβλήματα στο optimization αυτού.
    Μην αφήνετε τα media να σας "ταΐζουν"!
  •  06-02-2006, 18:25 9316 σε απάντηση της 9314

    Απ: Singleton Form

     infoCENTER wrote:
    Απο εκεί και πέρα όμως όταν κάνω dispose από την μεριά της εφαρμογής είναι σαν να λέω τελείωσα με αυτό το instance. Άρα θα έπρεπε το .Net ΜΟΝΟ του να βρει ποια άλλα references έχουν γίνει σε αυτό το instance και να τα θέσει Nothing. Αντί να υπάρχουν άστοχοι όπως γράφω pointers. Από εκεί και πέρα δεν το κάνει. Περιμένει απο εμάς να το κάνει και να γράψουμε mInstance=Nothing.

    H Dispose χρησιμοποιείται συνήθως για να κάνουμε release τα unmanaged resources (window handles, files, etc). Δηλαδή, όταν λέω objectX.Dispose δεν σημαίνει ότι το Framework θα κάνει κάτι. Εξαρτάται από το τι κώδικας υπάρχει μέσα στην Dispose. Αν ο developer που την έφτιαξε, κάνει Nothing κάποια objects τότε παύουν να υπάρχουν.

     infoCENTER wrote:
    Όσο για τον GC ας κανονίσει αυτός πότε θα καθαρίσει την μνήμη.

    Θα καθαρίσει τη μνήμη όταν δεν έχει άλλη διαθέσιμη ή τον καλέσουμε εμείς (πράγμα που γενικώς δεν θα πρέπει να κάνουμε).

     infoCENTER wrote:
    Κάποια στιγμή θα το κάνει, τότε η mInstance τι τιμή θα έχει; Που θα δείχνει; Τότε θα τεθεί σε Nothing; Ή θα δείχνει σε μία περιοχή μνήμης χωρίς δεδομένα;


    Οποιαδήποτε στιγμή τρέξω το statement mInstance=Nothing, πλέον παύω να έχω reference στο mInstance object, άσχετα αν υπάρχει ακόμα στη μνήμη ή όχι - αν θές άσχετα αν έχει τρέξει ο GC ή όχι. Ένα reference δεν υπάρχει ποτέ περίπτωση να δείξει σε περιοχή μνήμης που δεν έχει δεδομένα.


    Vir prudens non contra ventum mingit
  •  06-02-2006, 19:23 9317 σε απάντηση της 9316

    Απ: Singleton Form

    Παιδιά ξεφύγαμε. Έχουμε δώσει το βάρος στην Dispose. Δεν είναι εκεί το πρόβλημα. Το ξαναλέω. θα μπορούσε το mInstance=Nothing να ήταν στο Closed event της φόρμας. Θα μιλούσαμε για το closed event;

    Ίσως να φταίω και εγώ που δεν μπορώ να σας δώσω πιο λεπτομερειακά τον όλο προβληματισμό μου αλλά διαβάζοντας προσεχτικά τα posts μου ίσως να μπορέσετε να καταλάβετε τελικά τι εννοώ.

    Έχω μία shared μεταβλητή μέσα σε μία class. Η μεταβλητή αυτή είναι ένας pointer που δείχνει στο instance του class. Κάνω την class dispose. Για την εφαρμογή το συγκεκριμένο instance έχει τελειώσει. Ο pointer της μεταβλητής γιατί εξακολουθεί και δείχνει σε μία περιοχή δεδομένων που δεν είναι προσβάσιμη από την εφαρμογή όπως δείχνει το μήνυμα του compiler; Σε ένα managed περιβάλλον δεν θα έπρεπε να δείχνει σε Nothing; Γιατί πρέπει να το γράψω εγώ;

    Δεν μπορώ να το πω πιο απλά. Συγνώμη.
  •  06-02-2006, 19:43 9320 σε απάντηση της 9317

    Απ: Singleton Form

     infoCENTER wrote:
    Έχω μία shared μεταβλητή μέσα σε μία class. Η μεταβλητή αυτή είναι ένας pointer που δείχνει στο instance του class. Κάνω την class dispose. Για την εφαρμογή το συγκεκριμένο instance έχει τελειώσει. Ο pointer της μεταβλητής γιατί εξακολουθεί και δείχνει σε μία περιοχή δεδομένων που δεν είναι προσβάσιμη από την εφαρμογή όπως δείχνει το μήνυμα του compiler; Σε ένα managed περιβάλλον δεν θα έπρεπε να δείχνει σε Nothing; Γιατί πρέπει να το γράψω εγώ;

    Μιλάμε για την Dispose γιατί μάλλον έχεις παρεξηγήσει τη χρήση της. Αυτό που προσπαθώ να σου εξηγήσω είναι ότι όταν λές obj.Dispose δεν συνεπάγεται ότι το κάνεις nothing. Απλά κάνεις cleanup. Για παράδειγμα, αν έχεις ανοίξει ένα αρχείο - οποιονδήποτε unmanaged πόρο - το κάνεις release. Είναι ευθύνη του developer να γράψει κώδικα μέσα στην Dispose και μάλιστα υπάρχουν συγκεκριμένα guidelines που πρέπει να ακολουθήσει για να είναι σωστός ο κώδικας αυτός.

     


    Vir prudens non contra ventum mingit
  •  14-02-2006, 10:25 9656 σε απάντηση της 9320

    Απ: Singleton Form

    Και γιατί δεν την σηκώνεις modally:


    Dim fCustomersList as New CustomersGridViewForm

    With fCustomersList 
          .showDialog(Me) 
          .Dispose
    End with



    Πάνος Αβραμίδης
  •  14-02-2006, 10:26 9657 σε απάντηση της 9320

    Απ: Singleton Form

    Η static (shared) μεταβλητή σου είναι κοινή για όλα τα instances.

    Το γεγονός ότι "σκότωσες" ένα, δεν σημαίνει οτι αυτή η μεταβλητή δεν μπορεί να χρησιμοποιείται και από άλλα (που, στην περίπτωσή σου δεν υπάρχουν). Επομένως, γιατί πρέπει ο GC να το κάνει null (nothing); Αυτό θα έπρεπε να το κάνεις σε δική σου Dispose(). Προφανώς, το διαχειριζόμενο περιβάλλον εκτέλεσης (managed execution environment Smile [:)]) δεν ξέρει ότι υλοποιείς το singleton pattern ...

    Άρης


    Aris
Σελίδα 1 από 2 (25 εγγραφές)   1 2 >
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems