Το IDisposable interface στη γλώσσα C Sharp

Το IDisposable interface στη γλώσσα C Sharp

Το IDisposable interface στη γλώσσα C Sharp εκπροσωπεί έναν μηχανισμό για την αποδέσμευση πόρων του συστήματος που δε χρησιμοποιούνται από το πρόγραμμα. Ο πρωταρχικός σκοπός του interface είναι η απελευθέρωση τμημάτων πόρων και μνήμης που δεν αξιοποιούνται, προκειμένου να ελαχιστοποιηθεί ο αντίκτυπος μίας εφαρμογής στο λειτουργικό σύστημα που τη φιλοξενεί, και κατ’ επέκταση στις επιδόσεις αυτού.

Όταν το πρόγραμμα σταματά τη χρήση ενός αντικειμένου (π.χ. τερματισμός προγράμματος), ο garbage collector αυτομάτως απελευθερώνει τη δεσμευμένη μνήμη από το συγκεκριμένο αντικείμενο. Η μέθοδος δηλαδή προϋπάρχει και εκτελείται χωρίς προγραμματιστική παρέμβαση ή κλήση. Βέβαια δεν είναι εφικτό να προβλεφθεί ο χρόνος κατά τον οποίο πραγματοποιείται η διαδικασία αυτή, καθώς μπορεί να απέχει χρονικά από τον ουσιαστικό τερματισμό χρήσης του αντικειμένου.

Το IDisposable interface εφαρμόζεται ρητά μόνο στην περίπτωση που γίνεται απευθείας χρήση δεσμευμένων πόρων χωρίς την ύπαρξη αντικειμένου ως καταναλωτή. Εάν το πρόγραμμα περιλαμβάνει αντικείμενο ή έτοιμο component το οποίο έχει τη δυνατότητα κλήσης του IDisposable, τότε δεν απαιτείται εφαρμογή του interface. Αντί αυτού, καλείται η ομώνυμη μέθοδος για το συγκεκριμένο αντικείμενο.

Στη C# η εφαρμογή του interface πραγματοποιείται με έναν από τους εξής τρόπους:

  • Με τη χρήση ενός block κώδικα που ξεκινά με τη δεσμευμένη λέξη using χωρίς κλήση της μεθόδου
  • Με τη χρήση ενός block κώδικα try- catch- finally με κλήση της μεθόδου

Το IDisposable interface στη γλώσσα C Sharp: σύνταξη block  using χωρίς κλήση της μεθόδου

Έστω ότι έχουμε μία κλάση με όνομα TextManipulator, η οποία περιέχει μεθόδους για χειρισμό κειμένων, ως προς το περιεχόμενο και τη μορφοποίηση εμφάνισης. Μέσα σε αυτή θέλουμε να συντάξουμε μία μέθοδο για την αναζήτηση ενός μοτίβου σε ένα συγκεκριμένο κείμενο.

Ονομάζουμε τη μέθοδο FindMatches και ορίζουμε ότι θα επιστρέφει τιμή ακεραίου τύπου στο κυρίως πρόγραμμα, για να γνωρίζουμε πόσες φορές εντοπίστηκε συνολικά η επιθυμητή μας φράση. Ορίζουμε ότι θα δέχεται δύο ορίσματα τύπου συμβολοσειράς, με ονόματα file για το όνομα του αρχείου και word για το όνομα του μοτίβου που αναζητούμε στο κείμενο.

private int FindMatches(string file, string word)
{
    if (! File.Exists(file))
    {
       MessageBox.Show("Unable to find file or file does not exist..."); 
       return -1;
    }
    string myText =""; 
    using (StreamReader myReader = new StreamReader(file))     
    {       
       myText = myReader.ReadToEnd();     
    }     
    return( Regex.Matches(myText, word).Count ); 
}

Για τη μετατροπή του αρχείου σε κείμενο (string), δημιουργούμε ένα αντικείμενο της κλάσης StreamReader, ώστε να διοχετεύσει με ροή το περιεχόμενο του αρχείου μας στην τοπική μεταβλητή myText.

Παρατηρούμε τη χρήση της δεσμευμένης λέξης using ακριβώς πριν τη δημιουργία του StreamReader myReader, καθώς και τη χρήση των αγκυλών { και }. Με τον τερματισμό του συγκεκριμένου block κώδικα, το αντικείμενο myReader δεν υπάρχει πλέον στο πρόγραμμα. Οι πόροι που είχαν δεσμευτεί για αυτό έχουν ελευθερωθεί. Είναι προφανές ότι η δεσμευμένη λέξη Dispose( ) δε συντάσσεται, αλλά το IDisposable interface στη γλώσσα C Sharp είναι ενεργό και λειτουργεί αυτόματα για το αντικείμενό μας με τον τερματισμό της σύνταξης using.

Το IDisposable interface στη γλώσσα C Sharp:  σύνταξη block try- catch- finally με κλήση της μεθόδου

Στην περίπτωση που δε θέλουμε να ακολουθήσουμε τον πρώτο τρόπο, υπάρχει η δυνατότητα να καλέσουμε τη μέθοδο για το συγκεκριμένο αντικείμενο που χρησιμοποιούμε. Παρατίθεται ο κώδικας που εκτελεί την ίδια ακριβώς λειτουργία και επιστρέφει το ίδιο αποτέλεσμα, αξιοποιώντας όμως τη χρήση του block try-catch-finally προς αντικατάσταση του block using:

private int FindMatches(string file, string word)
{
   if (! File.Exists(file))
   {
     MessageBox.Show("Unable to find file or file does not exist..."); 
     return -1;
   } 
   string myText =""; 
   StreamReader myReader; 
   try 
   { 
      myReader = new StreamReader(file); 
      myText = myReader.ReadToEnd(); 
      return( Regex.Matches(myText, word).Count ); 
   } 
   catch 
   { 
      return -1; 
   } 
   finally 
   { 
      if (myReader != null) myReader.Dispose(); 
   } 
}

Η χρήση της μεθόδου  Dispose( ) χρησιμοποιείται για την αυθαίρετη απελευθέρωση πόρων του συστήματος, προλαμβάνοντας την αυτόματη λειτουργία του garbage collector. Ο προγραμματιστής μπορεί να καλέσει τη συγκεκριμένη μέθοδο, όταν κρίνει ότι η ύπαρξη ενός αντικειμένου αποτελεί πλεονασμό από ένα σημείο του προγράμματος και μετά. Η μέθοδος συνήθως δε χρησιμοποιείται για κλάσεις του προγραμματιστή, καθώς τα αντικείμενά τους δεν μπορούν να την καλέσουν άμεσα και επομένως δεν εξακριβώνεται εάν οι πόροι αποδεσμεύονται ουσιαστικά.

Απάντηση

Αυτός ο ιστότοπος χρησιμοποιεί το Akismet για να μειώσει τα ανεπιθύμητα σχόλια. Μάθετε πώς υφίστανται επεξεργασία τα δεδομένα των σχολίων σας.