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

Βέλτιστες πρακτικές σε .Net ασύγχρονο προγραμματισμό

Ο ασύγχρονος προγραμματισμός σάς επιτρέπει να εκτελείτε λειτουργίες εισόδου / εξόδου υψηλής έντασης πόρων χωρίς να χρειάζεται να μπλοκάρετε το κύριο ή το νήμα εκτέλεσης της εφαρμογής. Αν και είναι ευεργετικό και φαινομενικά εύκολο να εφαρμοστεί, έρχεται με πολλή πολυπλοκότητα και κινδύνους. Οι πιθανοί κίνδυνοι που συνδέονται με τον ασύγχρονο προγραμματισμό, ιδίως με τον ασύγχρονο προγραμματισμό με λάθος τρόπο, μη ακολουθώντας τις προτεινόμενες πρακτικές, περιλαμβάνουν αδιέξοδα, σφάλματα λειτουργίας και ακόμη και αργή απόδοση. Θα πρέπει επίσης να είναι ικανοί στη γραφή, τον εντοπισμό σφαλμάτων κώδικα ασύγχρονου κώδικα.

Αποφύγετε τον κενό τύπο επιστροφής στις μεθόδους ασύγχυσης

Μια μέθοδος στο C # γίνεται μια ασύγχρονη μέθοδος χρησιμοποιώντας τη λέξη-κλειδί async στην υπογραφή της μεθόδου. Μπορείτε να περιμένετε μία ή περισσότερες λέξεις-κλειδιά μέσα σε μια μέθοδο async. Η λέξη αναμονής χρησιμοποιείται για να δηλώσει το σημείο αναστολής. Μια μέθοδος async στο C # μπορεί να έχει οποιονδήποτε από αυτούς τους τύπους επιστροφής: Task, Task και void. Η λέξη-κλειδί "περιμένετε" χρησιμοποιείται σε μια μέθοδο ασύγχυσης για να ενημερώσει τον μεταγλωττιστή ότι η μέθοδος μπορεί να έχει ένα σημείο αναστολής και επαναφοράς.

Σημειώστε ότι κατά τη χρήση του TPL, το ισοδύναμο της επιστροφής κενού στο TPL είναι async Task. Θα πρέπει να γνωρίζετε ότι το άκυρο άκυρο χρησιμοποιείται και πρέπει να χρησιμοποιείται μόνο για συμβάντα ασύγχυσης. Εάν το χρησιμοποιήσετε οπουδήποτε αλλού, θα αντιμετωπίσετε σφάλματα. Με άλλα λόγια, δεν συνιστάται μια μέθοδος ασύγχρονης που έχει άκυρο ως τύπο επιστροφής. επειδή οι μέθοδοι ασύγχρονου που επιστρέφουν άκυρες έχουν διαφορετική σημασιολογία όταν εργάζεστε με εξαιρέσεις στην εφαρμογή σας.

Όταν συμβαίνει μια εξαίρεση σε μια μέθοδο async που έχει έναν τύπο επιστροφής Task ή Task, το αντικείμενο εξαίρεσης αποθηκεύεται μέσα στο αντικείμενο Task. Αντίθετα, εάν έχετε μια μέθοδο async με τύπο επιστροφής κενού, δεν υπάρχει συσχετισμένο αντικείμενο εργασίας. Τέτοιες εξαιρέσεις δημιουργούνται στο SynchronizationContext που ήταν ενεργό τη στιγμή που κλήθηκε η ασύγχρονη μέθοδος. Με άλλα λόγια, δεν μπορείτε να χειριστείτε τις εξαιρέσεις που δημιουργούνται σε μια μέθοδο άκυρου άκυρου χρησιμοποιώντας χειριστές εξαιρέσεων γραμμένες μέσα στην ασύγχρονη μέθοδο. Οι μέθοδοι Async που έχουν τύπο επιστροφής κενού είναι επίσης δύσκολο να ελεγχθούν λόγω αυτής της διαφοράς στη σημασιολογία χειρισμού σφαλμάτων. Για την ενημέρωσή σας, η κλάση SynchronizationContext στο System. Το πεδίο ονομάτων νήματος αντιπροσωπεύει ένα πλαίσιο συγχρονισμού στο .Net και σας βοηθά να κάνετε ουρά σε μια εργασία σε άλλο περιβάλλον.

Η ακόλουθη λίστα κωδικών το δείχνει αυτό. Έχετε δύο μεθόδους, συγκεκριμένα, Test and TestAsync και η τελευταία ρίχνει μια εξαίρεση.

δημόσια τάξη AsyncDemo

   {

Δημόσιο κενό ()

       {

δοκιμάστε

           {

TestAsync ();

           }

αλίευση (πρώην εξαίρεση)

           {

Console.WriteLine (π.χ. Μήνυμα);

           }

       }

private async void TestAsync ()

       {

ρίξτε νέα εξαίρεση ("Αυτό είναι ένα μήνυμα σφάλματος").

       }

   }

Δείτε πώς μπορείτε να δημιουργήσετε μια παρουσία της κλάσης AsyncDemo και να καλέσετε τη μέθοδο δοκιμής.

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

       {

AsyncDemo obj = νέο AsyncDemo ();

obj.Test ();

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

       }

Η μέθοδος δοκιμής πραγματοποιεί μια κλήση στη μέθοδο TestAsync και η κλήση τυλίγεται μέσα σε ένα μπλοκ δοκιμής με σκοπό την αντιμετώπιση της εξαίρεσης που ρίχνεται μέσα στη μέθοδο TestAsync. Ωστόσο, η εξαίρεση που ρίχνεται μέσα στη μέθοδο TestAsync δεν θα παγιδευτεί ποτέ, δηλαδή θα αντιμετωπιστεί μέσα στη δοκιμή μεθόδου καλούντος.

Αποφύγετε την ανάμιξη ασύγχρονου και σύγχρονου κώδικα

Δεν πρέπει ποτέ να έχετε συνδυασμό συγχρονισμένου και ασύγχρονου κώδικα. Είναι μια κακή πρακτική προγραμματισμού να αποκλείσετε τον κώδικα ασύγχρονης πραγματοποίησης κλήσεων στο Task.Wait ή Task.Result. Θα συνιστούσα τη χρήση κωδικού async από άκρο σε άκρο - είναι ο ασφαλέστερος τρόπος για να αποφύγετε τα σφάλματα να εισέρχονται.

Μπορείτε να αποφύγετε τα αδιέξοδα χρησιμοποιώντας.ConfigureAwait (συνέχειαOnCapturedContext: false) όποτε κάνετε μια κλήση για να περιμένετε. Εάν δεν το χρησιμοποιείτε, η μέθοδος ασύγχρονης λειτουργίας θα μπλοκάρει στο σημείο όπου κλήθηκε η αναμονή. Σε αυτήν την περίπτωση απλώς ενημερώνετε τον σερβιτόρο για να μην καταγράψετε το τρέχον πλαίσιο. Θα έλεγα ότι είναι καλή πρακτική να χρησιμοποιείτε το .ConfigureAwait (false) εκτός εάν έχετε συγκεκριμένο λόγο να μην το χρησιμοποιήσετε.

Θα συζητούσα περισσότερα σχετικά με τον ασύγχρονο προγραμματισμό στις μελλοντικές αναρτήσεις ιστολογίου μου εδώ. Για περισσότερες πληροφορίες σχετικά με τις βέλτιστες πρακτικές στον ασύγχρονο προγραμματισμό, μπορείτε να ανατρέξετε στο εξαιρετικό άρθρο του Stephen Cleary στο MSDN.