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

Στις μεθόδους Task.Factory.StartNew και Task.Run

Όταν δημιουργείτε εργασίες χρησιμοποιώντας μεθόδους Task.Factory.StartNew ή Task.Run, πρέπει να έχετε κατά νου ορισμένα σημαντικά σημεία κατά τη σύνταξη ασύγχρονου κώδικα. Στις περισσότερες περιπτώσεις, συνιστάται να αποφεύγετε τη χρήση της μεθόδου Task.Factory.StartNew εάν εργάζεστε με ασύγχρονο κώδικα. Εάν εργάζεστε με παράλληλο κώδικα, θα έλεγα ότι το StartNew είναι μια καλή επιλογή.

Ένας προγραμματιστής εργασιών είναι ένα στοιχείο που είναι υπεύθυνο για τον προγραμματισμό εργασιών. Το πλαίσιο .Net σάς παρέχει δύο προγραμματιστές εργασιών. Υπάρχει ο προεπιλεγμένος προγραμματιστής εργασιών που τρέχει στην ομάδα νήματος πλαισίου .Net και υπάρχει ο προγραμματιστής εργασιών που εκτελείται στο πλαίσιο συγχρονισμού ενός καθορισμένου στόχου. Ο προεπιλεγμένος προγραμματιστής εργασιών θα επαρκεί τις περισσότερες φορές, αλλά μπορείτε επίσης να δημιουργήσετε το δικό σας προσαρμοσμένο χρονοδιάγραμμα εργασιών για να παρέχετε πρόσθετες λειτουργίες. Για να δημιουργήσετε το δικό σας προσαρμοσμένο χρονοδιάγραμμα εργασιών, θα πρέπει να δημιουργήσετε μια κλάση που επεκτείνει την κλάση System.Threading.Tasks.TaskScheduler.

Πώς δημιουργώ Tasks χρησιμοποιώντας τη Task Parallel Library;

Υπάρχουν διάφοροι τρόποι με τους οποίους μπορείτε να δημιουργήσετε και να ξεκινήσετε εργασίες στο .Net. Πρέπει να χρησιμοποιήσετε το System.Threading.Tasks.Task ή System.Threading.Tasks.Task class για να δημιουργήσετε εργασίες (μια προγραμματιζόμενη μονάδα εργασίας). Ενώ η πρώτη χρησιμοποιείται για τη δημιουργία μιας εργασίας που δεν επιστρέφει μια τιμή, η δεύτερη χρησιμοποιείται για τη δημιουργία εργασιών που έχουν τιμές επιστροφής. Η ιδιότητα Task.Factory είναι μια παρουσία της κλάσης TaskFactory. Αυτή η ιδιότητα χρησιμοποιείται για τη δημιουργία και τον προγραμματισμό εργασιών. Ενώ η μέθοδος Task.Factory.StartNew λειτουργεί σαν μια λειτουργία πιρουνιού και χρησιμοποιείται για τη δημιουργία και την εκκίνηση νέων εργασιών, η μέθοδος Wait λειτουργεί ακριβώς όπως μια λειτουργία σύνδεσης και περιμένει την ολοκλήρωση της εργασίας.

Το ακόλουθο απόσπασμα κώδικα δείχνει πώς μπορείτε να χρησιμοποιήσετε τη μέθοδο Task.Factory.StartNew.

Task.Factory.StartNew (() => TestMethod (), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);

Μπορείτε επίσης να δημιουργήσετε μια εργασία χρησιμοποιώντας τη μέθοδο Task.Run, όπως φαίνεται στο παρακάτω απόσπασμα κώδικα.

public async Εργασία DoSomeWork ()

        {

περιμένετε Task.Run (() => TestMethod ());

        }

άκυρη δοκιμαστική μέθοδος ()

        {

Console.WriteLine ("Γεια σου κόσμος!");

        }

Εάν θέλετε να επιστρέψετε μια τιμή από μια εργασία, μπορείτε να επωφεληθείτε από τη μέθοδο Task.FromResult όπως φαίνεται στο απόσπασμα κώδικα παρακάτω.

public async Εργασία DoSomeWork ()

   {

string text = αναμονή Task.FromResult (GetMessage ());

   }

ιδιωτική συμβολοσειρά GetMessage ()

   {

επιστρέψτε "Γεια σου κόσμος!";

   }

Μπορείτε επίσης να δημιουργήσετε εργασίες χρησιμοποιώντας έναν πληρεξούσιο ή μια ενέργεια. Το παρακάτω απόσπασμα κώδικα δείχνει πώς μπορείτε να δημιουργήσετε εργασίες χρησιμοποιώντας ενέργειες και εκπροσώπους.

Task task1 = new Task (new Action (Display));

task1. Έναρξη ();

Task task2 = new Task (πληρεξούσιο {Display ();});

task2. Έναρξη ();

Μπορείτε επίσης να δημιουργήσετε εργασίες χρησιμοποιώντας μεθόδους lamba και ανώνυμες.

Task.Factory.StartNew και Task.Run

Το Task.Factory.StartNew είναι ένας γρήγορος τρόπος δημιουργίας και έναρξης μιας εργασίας. Σημειώστε ότι μια κλήση στο Task.Factory.StartNew είναι λειτουργικά ισοδύναμη με τη δημιουργία μιας παρουσίας εργασίας και, στη συνέχεια, την κλήση της μεθόδου Έναρξη στην παρουσία. Ωστόσο, δεν συνιστάται να χρησιμοποιείται για πολλούς λόγους. Αν θέλετε να εκτελέσετε σύγχρονο κώδικα, το Task.Factory.StartNew δεν είναι καλή επιλογή.

Σημειώστε ότι εάν είναι διαθέσιμος ένας προγραμματιστής εργασιών, η μέθοδος StartNew θα εκτελέσει την εργασία σε αυτόν τον προγραμματιστή εργασιών. Αντίθετα, εάν ένας προγραμματιστής δεν είναι διαθέσιμος, θα εκτελούσε την εργασία σε ένα νήμα συγκέντρωσης νήματος. Πρέπει να σημειωθεί ότι το Task.Factory.StartNew είναι προεπιλεγμένο στο TaskScheduler.Current και όχι στο TaskScheduler.Default.

Σημειώστε ότι μια κλήση στο Task.Run (action) ισοδυναμεί με την ακόλουθη δήλωση: Task.Factory.StartNew (ενέργεια, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);

Αντίθετα, μια κλήση στο Task.Factory.StartNew (ενέργεια) ισοδυναμεί με την ακόλουθη δήλωση:

Task.Factory.StartNew (ενέργεια, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Current);

Εάν μπορεί να θέλετε να χρησιμοποιήσετε το Task.Factory.StartNew εάν έχετε δημιουργήσει έναν προσαρμοσμένο χρονοδιακόπτη εργασιών και μεταβιβάζετε την παρουσία προγραμματιστή σε αυτήν ρητά. Θα συνιστούσα πάντα τη χρήση του Task.Run καθώς είναι πολύ πιο απλό και έχει ασφαλέστερες προεπιλογές. Με άλλα λόγια, θα πρέπει να αποφύγουμε τη χρήση του Task.Factory.StartNew, εκτός εάν υπάρχει ανάγκη δημιουργίας χρονοδιαγράμματος εργασιών και, στη συνέχεια, να το περάσουμε ρητά όταν καλείτε τη μέθοδο StartNew για να δημιουργήσετε μια νέα εργασία και να προγραμματίσετε. Εάν επρόκειτο να χρησιμοποιήσετε τη μέθοδο TaskFactory.StartNew αποτελεσματικά και αξιόπιστα, θα πρέπει να χρησιμοποιήσετε έναν προσαρμοσμένο χρονοδιάγραμμα εργασιών και, στη συνέχεια, να καθορίσετε το CancellationToken και το TaskCreationOptions.

Η μέθοδος Task.Run συνιστάται να χρησιμοποιείται όταν δεν χρειάζεται να έχετε πολύ λεπτομερή έλεγχο του προγραμματισμού νήματος και των περιπλοκών του. Θα πρέπει να χρησιμοποιήσετε το Task.Run κυρίως σε μεθόδους συνδεδεμένες με CPU. Ωστόσο, θα πρέπει να χρησιμοποιήσετε το Task.Run κατά την επίκληση της εργασίας και όχι εντός της εκτέλεσης της εργασίας. Με άλλα λόγια, πρέπει να χρησιμοποιήσετε το Task. Εκτελέστε όχι μέσα σε οποιαδήποτε εφαρμογή μιας μεθόδου αλλά στο σημείο όπου καλείται η μέθοδος. Για παράδειγμα, το ακόλουθο απόσπασμα κώδικα είναι ένα παράδειγμα ενός "κακού" κομματιού κώδικα.

public async Εργασία Λήψη DataFromWebAsync (Uri ουρι)

        {

επιστροφή περιμένετε Task.Run (() =>

            {

χρήση (WebClient webClient = νέο WebClient ())

                {

επιστροφή webClient.DownloadString (ουρι);

                }

            });

        }

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