Προγραμματισμός

Τα δύο σεντ μου στο Thread.Abort και Thread. Διακοπές μέθοδοι

Στο C #, ίσως χρειαστεί συχνά να απελευθερώσετε ένα νήμα που έχει αποκλειστεί. Για να επιτευχθεί αυτό, υπάρχουν δύο μέθοδοι που μπορείτε να επωφεληθείτε. Αυτές περιλαμβάνουν τις μεθόδους Thread.Abort και Thread.Interrupt.

Τι κάνει η μέθοδος Thread.Abort;

Για να τερματίσετε ένα νήμα, μπορείτε να επωφεληθείτε από τη μέθοδο Abort της κλάσης Thread. Σημειώστε ότι για να ξεκινήσετε τη διαδικασία τερματισμού ενός νήματος, η μέθοδος Abort της κλάσης Thread όταν καλείται, δημιουργεί ένα ThreadAbortException στο νήμα στο οποίο έχει κληθεί. Θα πρέπει να σημειωθεί ότι μπορείτε να επωφεληθείτε από τη μέθοδο Abort της κλάσης Thread για να τερματίσετε ακόμη και ένα μη αποκλεισμένο νήμα. Εάν το νήμα που διακόπτεται βρίσκεται σε κατάσταση αναμονής, το ξυπνά και στη συνέχεια προκαλεί τη ρίψη ενός ThreadInterruptException. Ομοίως, εάν καλέσετε τη μέθοδο Thread.Abort σε ένα νήμα που βρίσκεται σε κατάσταση αναμονής, ο χρόνος εκτέλεσης ξυπνά το νήμα και στη συνέχεια ρίχνει ένα ThreadAbortException.

Μπορείτε να πιάσετε το ThreadAbortException στο μπλοκ catch. Ωστόσο, εάν δεν καλέσετε τη μέθοδο ResetAbort, αυτή η εξαίρεση θα εμφανιστεί ξανά στο τέλος του μπλοκ catch. Η κλήση στη μέθοδο ResetAbort θα αποτρέψει το ThreadAbortException από το να ρίξει ξανά στο τέλος του μπλοκ catch. Σε αντίθεση με τον τρόπο λειτουργίας των μεθόδων Thread.Inturrupt, εάν το νήμα στο οποίο καλείται η μέθοδος Thread.Abort δεν έχει αποκλειστεί, η μέθοδος Thread.Abort ρίχνει ένα ThreadAbortException στο νήμα.

Στις περισσότερες περιπτώσεις (εκτός και αν θέλετε να τερματίσετε τον τομέα της εφαρμογής μετά την ακύρωση ενός νήματος), δεν χρειάζεται να χρησιμοποιήσετε αυτήν τη μέθοδο καθόλου. Σημειώστε ότι η μέθοδος Response.Redirect στο ASP.Net ρίχνει ένα ThreadAbortException.

Ποιος είναι ο σκοπός της μεθόδου Thread.Interrupt;

Μπορείτε να χρησιμοποιήσετε τη μέθοδο Thread.Interrupt για να διακόψετε ένα νήμα που βρίσκεται σε κατάσταση WaitSleepJoin. Ωστόσο, καμία από αυτές τις προσεγγίσεις (Thread.Abort ή Thread.Interrupt μέθοδοι κλήσεις) δεν είναι ασφαλής στο νήμα. Ενώ η μέθοδος Thread.Abort ρίχνει ένα ThreadAbortException, η μέθοδος Thread.Inbrupt ρίχνει ένα ThreadInterruptException. Ουσιαστικά, μια κλήση στο Thread.Interrupt μέθοδο διακόπτει το νήμα και ρίχνει ένα ThreadInterruptException για να διακόψει το νήμα μέσα σε μια κλήση αποκλεισμού. Θα πρέπει να χειριστείτε αυτήν την εξαίρεση στον κώδικά σας, αποτυπώνοντας ποιος χρόνος εκτέλεσης θα σταματήσει το νήμα στο οποίο έχει κληθεί η μέθοδος Thread. Θα πρέπει να σημειωθεί ότι μια κλήση στο Thread.Interrupt δεν διακόπτει ένα νήμα που εκτελεί μη διαχειριζόμενο κώδικα.

Εξετάστε την ακόλουθη λίστα κωδικών που απεικονίζει πώς μπορεί να κληθεί η μέθοδος Thread.Interrupt για να διακόψετε βίαια ένα νήμα.

static void Main (συμβολοσειρά [] args)

       {

Νήμα νήματος = νέο νήμα (ThreadMethod);

νήμα. Έναρξη ();

νήμα. Διακοπή ();

Κονσόλα. Διαβάστε ();

       }

ιδιωτικό στατικό κενό ThreadMethod ()

       {

δοκιμάστε

           {

Νήμα. Sleep (Timeout.Infinite);

           }

πιάσιμο (ThreadInterruptException)

           {

Console.Write ("Το ThreadInterruptException κλήθηκε βίαια.");

           }

       }

Όταν εκτελείται το παραπάνω πρόγραμμα, θα εμφανιστεί το μήνυμα "ThreadInterruptException βίαια" στην κονσόλα.

Τι συμβαίνει εάν το νήμα που διακόπτεται δεν έχει αποκλειστεί; Σας κάνω μια κλήση στο νήμα. Διακοπή σε ένα νήμα που δεν έχει αποκλειστεί, το νήμα θα συνεχίσει να εκτελείται μέχρι τη στιγμή που θα μπλοκαριστεί στη συνέχεια. Στις περισσότερες περιπτώσεις, δεν χρειάζεται να χρησιμοποιήσετε το νήμα. Διακοπή καθόλου. Μπορείτε να επιτύχετε το ίδιο χρησιμοποιώντας κατασκευές σηματοδότησης ή μάρκες ακύρωσης.

Πρέπει να χρησιμοποιήσω τη μέθοδο Thread.Abort ή Thread.Interrupt;

Λοιπόν, πότε πρέπει να χρησιμοποιήσω το Thread.Abort vs Thread. Διακοπές μέθοδοι στο πρόγραμμά μου; Εάν πρέπει να ακυρώσω μια συγκεκριμένη λειτουργία, ποια από αυτές τις μεθόδους πρέπει να χρησιμοποιήσω; Η ειλικρινή μου απάντηση είναι ότι δεν πρέπει ποτέ να χρησιμοποιείτε καμία από αυτές τις μεθόδους για να τερματίσετε ένα νήμα. Συνιστάται να μην χρησιμοποιείτε το Thread.Abort ή Thread. Διακοπές μέθοδοι για τον τερματισμό ενός νήματος - μάλλον θα πρέπει να επωφεληθείτε από αντικείμενα συγχρονισμού (όπως, WaitHandles ή Semaphores) και να εκτελέσετε έναν χαριτωμένο τερματισμό των νημάτων που χρησιμοποιείτε. Το ακόλουθο απόσπασμα κώδικα δείχνει πώς μπορείτε να επωφεληθείτε από ένα WaitHandle για να επιτρέψετε σε ένα νήμα να σταματήσει χαριτωμένα.

ιδιωτικό κενό ThreadMethod ()

{

ενώ (! manualResetEventObject.WaitOne (TimeSpan.FromMilliseconds (100)))

   {

// Γράψτε τον κωδικό σας εδώ

   }

}

Ως εναλλακτική προσέγγιση για τον τερματισμό ενός νήματος με χαρά, μπορείτε επίσης να επωφεληθείτε από μια πτητική "boolean" μεταβλητή. Στη συνέχεια, μπορείτε να ορίσετε αυτήν τη μεταβλητή στο νήμα διεπαφής χρήστη σε κάποια δραστηριότητα χρήστη (υποθέστε ότι ο χρήστης έχει κάνει κλικ στο κουμπί "Ακύρωση" στο περιβάλλον χρήστη για να τερματίσει το νήμα) και, στη συνέχεια, ελέγξτε την τιμή της μεταβλητής κατά καιρούς στο Worker νήμα για να δείτε αν η μεταβλητή έχει οριστεί (ίσως μια τιμή "false" για να δείξει τον τερματισμό του νήματος) στο περιβάλλον χρήστη.

$config[zx-auto] not found$config[zx-overlay] not found