Τρόπος κλήσης ασύγχρονη μέθοδο Visual C#

Σύνοψη

Το Microsoft .NET Framework εύκολα να καλέσετε συναρτήσεις ασύγχρονα. Κλήση συναρτήσεων ασύγχρονη έχει ως αποτέλεσμα το σύστημα να εκτελέσει στο παρασκήνιο σε ένα δευτερεύον νήμα, όταν η καλούσα συνάρτηση συνεχίζει να κάνετε άλλες εργασίες. Σε κλήση τυπική συνάρτηση (σύγχρονη), η συνάρτηση εκτελείται αμέσως στο ίδιο νήμα που κάνει την κλήση. Η κλήση της λειτουργίας περιμένει να ολοκληρωθεί η κλήση και λαμβάνει τα αποτελέσματα της κλήσης πριν να συνεχίσετε. Αντίθετα, όταν κάνετε μια ασύγχρονη κλήση, μπορείτε να ανακτήσετε τα αποτελέσματα της ασύγχρονης κλήσης αργότερα. Αυτό το άρθρο παρουσιάζει τον τρόπο για να το κάνετε χρησιμοποιώντας το Visual C#.

Απαιτήσεις


Η ακόλουθη λίστα περιγράφει το υλικού που συνιστώνται, λογισμικό, υποδομή δικτύου και τα service pack που απαιτούνται:
  • Τα Windows 2000 ή Microsoft Windows XP ή Microsoft Windows Server 2003
  • Visual Studio .NET ή Visual Studio 2005
Αυτό το άρθρο προϋποθέτει ότι είστε εξοικειωμένοι με τα ακόλουθα θέματα:
  • Κλήση μεθόδων σε Visual C#
  • Τρόπος χρήσης των πληρεξουσίων

Πώς μπορείτε να κάνετε ασύγχρονη κλήσεις

Ασύγχρονη κλήσεις γίνονται χρησιμοποιώντας πληρεξούσιους. Ένας πληρεξούσιος είναι ένα αντικείμενο που περικλείει μια συνάρτηση. Οι πληρεξούσιοι παρέχουν μια σύγχρονη λειτουργία και παρέχει επίσης μεθόδους για την κλήση της συνάρτησης αναδιπλωμένο ασύγχρονα. Οι μέθοδοι αυτές είναι BeginInvoke() και EndInvoke(). Οι λίστες παραμέτρων από αυτές τις μεθόδους ποικίλλουν ανάλογα με την υπογραφή της συνάρτησης που περικλείει τον πληρεξούσιο. Σημειώστε ότι η δυνατότητα του Visual Studio .NET το IntelliSense δεν εμφανίζει BeginInvoke() και EndInvoke(), έτσι δεν βλέπετε τους εμφανίζονται στις λίστες λειτουργία κατά την πληκτρολόγηση.


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

Η συνάρτηση EndInvoke() χρησιμοποιείται για να ανακτήσετε τα αποτελέσματα της ασύγχρονης κλήσης. Μπορεί να κληθεί οποιαδήποτε στιγμή μετά την BeginInvoke(). Εάν η ασύγχρονη κλήση δεν έχει ολοκληρωθεί ακόμα, EndInvoke() μπλοκ μέχρι να ολοκληρωθεί. Οι παράμετροι της συνάρτησης EndInvoke() περιλαμβάνει ανάληψη και
παράμετροι REF που έχει η συνάρτηση αναδίπλωση, συν το αντικείμενο IAsyncResult που επιστρέφονται από BeginInvoke().

Ακολουθεί ένα παράδειγμα έναν πληρεξούσιο και τις μεθόδους BeginInvoke() και EndInvoke() :
// The following delegate delegate string MethodDelegate(int iCallTime, out int iExecThread)  ;

// will have the following BeginInvoke() and EndInvoke methods:
IAsyncResult MethodDelegate.BeginInvoke(int iCallTime, out int iExecThread, AsyncCallback cb, object AsyncState);

string MethodDelegate.EndInvoke (out int iExecThread, IAsyncResult ar) ;

Υπάρχουν τέσσερις συνηθισμένοι τρόποι χρήσης BeginInvoke() και EndInvoke() για να πραγματοποιείτε κλήσεις ασύγχρονων. Μετά την κλήση BeginInvoke(), μπορείτε να:
  • Προαιρετικά κάποια άλλη εργασία και, στη συνέχεια, χρησιμοποιείτε EndInvoke().
  • Αποκτήστε ένα WaitHandle που παρέχεται από το αντικείμενο IAsyncResult , χρησιμοποιήστε τη μέθοδο WaitOne για να αποκλείσετε μόνο όταν το WaitHandle και στη συνέχεια καλέστε EndInvoke().
  • Σταθμοσκόπηση το αντικείμενο IAsyncResult για να προσδιορίσετε όταν ολοκληρωθεί η ασύγχρονη κλήση και, στη συνέχεια, καλέστε EndInvoke().
  • Έχουν το σύστημα κλήση μιας συνάρτησης επιστροφής κλήσης που έχετε καθορίσει. Αυτή η λειτουργία επιστροφής κλήσης καλεί EndInvoke() και επεξεργάζεται τα αποτελέσματα της ασύγχρονης κλήσης όταν ολοκληρωθεί.
Τα ακόλουθα δείγματα κώδικα παρουσιάζουν αυτές καλούν μοτίβα και τους σε αντιδιαστολή με κάνοντας μια σύγχρονη κλήση, χρησιμοποιώντας την ακόλουθη συνάρτηση:
string LongRunningMethod (int iCallTime, out int iExecThread){
Thread.Sleep (iCallTime) ;
iExecThread = AppDomain.GetCurrentThreadId ();
return "MyCallTime was " + iCallTime.ToString() ;
}


LongRunningMethod() αναπαριστά μια συνάρτηση η οποία εκτελείται για μεγάλο χρονικό διάστημα, σε αναστολή λειτουργίας. Επιστρέφει το χρόνο αναστολής λειτουργίας και το Αναγνωριστικό του νήματος που εκτελεί. Εάν καλέσετε ασύγχρονα, διαπιστώνετε ότι το Αναγνωριστικό νήματος του νήματος εκτέλεση είναι διαφορετικό από αυτό της συνομιλίας.

Το πρώτο βήμα είναι να ορίσετε τον πληρεξούσιο που περικλείει τη συνάρτηση:
delegate string MethodDelegate(int iCallTime, out int iExecThread)  ;

Δείγμα 1: Κλήση μιας μεθόδου τη σύγχρονη

Αυτό το δείγμα παρουσιάζει πώς μπορείτε να καλείτε τη σύγχρονη LongRunningMethod() , χρησιμοποιώντας έναν πληρεξούσιο MethodDelegate . Υπολοίπων δειγμάτων έρχεται σε αντιδιαστολή με τηλεφωνήματα ασύγχρονα.
  1. Ξεκινήστε το Microsoft Visual Studio .NET ή Microsoft Visual Studio 2005.
  2. Δημιουργήστε ένα νέο έργο Visual C# κονσόλα εφαρμογής με το όνομα AsyncDemo.
  3. Για να προσθέσετε μια κλάση με το όνομα AsyncDemo που έχει οριστεί για το έργο σε ένα νέο αρχείο .cs ως εξής:
    using System;using System.Threading ; 
    using System.Windows.Forms ;

    public class AsyncDemo
    {
    string LongRunningMethod (int iCallTime, out int iExecThread)
    {
    Thread.Sleep (iCallTime) ;
    iExecThread = AppDomain.GetCurrentThreadId ();
    return "MyCallTime was " + iCallTime.ToString() ;
    }

    delegate string MethodDelegate(int iCallTime, out int iExecThread) ;

    public void DemoSyncCall()
    {
    string s ;
    int iExecThread;

    // Create an instance of a delegate that wraps LongRunningMethod.
    MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;

    // Call LongRunningMethod using the delegate.
    s = dlgt(3000, out iExecThread);

    MessageBox.Show (string.Format ("The delegate call returned the string: \"{0}\",
    and the thread ID {1}", s, iExecThread.ToString() ) );
    }
    }

    Αργότερα, αυτή η κλάση παρουσιάζει πώς μπορείτε να κάνετε ασύγχρονη κλήσεις. Αρχικά, ωστόσο, περιέχει μόνο τη μέθοδο DemoSyncCall() , η οποία παρουσιάζει πώς μπορείτε να καλέσετε τη σύγχρονη ο πληρεξούσιος.
  4. Προσθέστε τον ακόλουθο κώδικα στο κύριο μέρος του λειτουργία που δημιουργεί αυτόματα Visual Studio στο έργο σας :
    static void Main(string[] args){
    AsyncDemo ad = new AsyncDemo () ;
    ad.DemoSyncCall() ;
    }

  5. Πιέστε το συνδυασμό πλήκτρων CTRL + F5 για να εκτελέσουν την εφαρμογή σας.

Δείγμα 2: Κλήση μιας μεθόδου γίνεται ασύγχρονα χρησιμοποιώντας το μοτίβο κλήσης EndInvoke()

Σε αυτήν την ενότητα, το δείγμα καλεί την ίδια μέθοδο ασύγχρονα. Είναι το μοτίβο κλήσης που χρησιμοποιείται για την κλήση BeginInvoke, κάνετε κάποια εργασία στο κύριο νήμα, και στη συνέχεια καλείτε EndInvoke(). Σημειώστε ότι EndInvoke() δεν επιστρέφει μέχρι να ολοκληρωθεί η ασύγχρονη κλήση. Αυτό το μοτίβο κλήσης είναι χρήσιμη όταν θέλετε να έχετε συνομιλίας λειτουργούν ταυτόχρονα με την εκτέλεση της ασύγχρονης κλήσης. Έχουν παρουσιαστεί ταυτόχρονα την εργασία μπορεί να βελτιώσει την απόδοση από τις πολλές εφαρμογές. Κοινές εργασίες για να εκτελούνται με ασύγχρονο τρόπο με αυτόν τον τρόπο είναι λειτουργιών αρχείου ή δικτύου.
  1. Προσθέστε μια μέθοδο με το όνομα DemoEndInvoke() στην κλάση AsyncDemo . Η συνάρτηση DemoEndInvoke παρουσιάζει πώς μπορείτε να καλέσετε τον πληρεξούσιο ασύγχρονα.
    public void DemoEndInvoke(){
    MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;
    string s ;
    int iExecThread;

    // Initiate the asynchronous call.
    IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, null, null);

    // Do some useful work here. This would be work you want to have
    // run at the same time as the asynchronous call.

    // Retrieve the results of the asynchronous call.
    s = dlgt.EndInvoke (out iExecThread, ar) ;

    MessageBox.Show (string.Format ("The delegate call returned the string: \"{0}\",
    and the number {1}", s, iExecThread.ToString() ) );
    }

  2. Επεξεργαστείτε τον κώδικα προέλευσης για κύρια ώστε να περιέχει τον ακόλουθο κώδικα:
    static void Main(string[] args){
    AsyncDemo ad = new AsyncDemo () ;
    ad.DemoEndInvoke() ;
    }

  3. Πιέστε το συνδυασμό πλήκτρων CTRL + F5 για να εκτελέσουν την εφαρμογή σας.

Δείγμα 3: Κλήση μιας μεθόδου γίνεται ασύγχρονα και χρησιμοποιώντας ένα WaitHandle σε αναμονή για την κλήση για να ολοκληρωθεί


Σε αυτήν την ενότητα, το δείγμα καλεί τη μέθοδο ασύγχρονα και αναμένει ένα WaitHandle πριν καλεί EndInvoke(). Το IAsyncResult που επιστρέφεται από BeginInvoke() έχει μια ιδιότητα AsyncWaitHandle . Αυτή η ιδιότητα επιστρέφει ένα WaitHandle που σηματοδοτείται όταν ολοκληρωθεί η ασύγχρονη κλήση. Σε ένα WaitHandle αναμονή είναι μια κοινή τεχνική συγχρονισμού νήμα. Το νήμα κλήσης αναμένει το WaitHandle χρησιμοποιώντας τη μέθοδο WaitOne() του WaitHandle. Μπλοκ WaitOne() μόνο όταν η WaitHandle . Όταν επιστρέφει WaitOne() , μπορείτε να κάνετε κάποια πρόσθετη εργασία πριν από την κλήση του EndInvoke(). Όπως και στο προηγούμενο δείγμα, η τεχνική αυτή είναι χρήσιμη για την εκτέλεση λειτουργιών αρχείου ή δικτύου που διαφορετικά θα απέκλειαν το κύριο νήμα κλήσης.
  1. Για να προσθέσετε μια συνάρτηση με όνομα DemoWaitHandle() στην κλάση AsyncDemo . Η συνάρτηση DemoWaitHandle() παρουσιάζει πώς μπορείτε να καλέσετε τον πληρεξούσιο ασύγχρονα.
    public void DemoWaitHandle (){
    string s ;
    int iExecThread;

    MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;

    // Initiate the asynchronous call.
    IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, null, null);

    // Do some useful work here. This would be work you want to have
    // run at the same time as the asynchronous call.

    // Wait for the WaitHandle to become signaled.
    ar.AsyncWaitHandle.WaitOne() ;

    // Get the results of the asynchronous call.
    s = dlgt.EndInvoke (out iExecThread, ar) ;

    MessageBox.Show (string.Format ("The delegate call returned the string: \"{0}\",
    and the number {1}", s, iExecThread.ToString() ) );
    }

  2. Επεξεργαστείτε τον κώδικα προέλευσης για κύρια ώστε να περιέχει τον ακόλουθο κώδικα:
    static void Main(string[] args){
    AsyncDemo ad = new AsyncDemo () ;
    ad.DemoWaitHandle () ;
    }

  3. Πιέστε το συνδυασμό πλήκτρων CTRL + F5 για να εκτελέσουν την εφαρμογή σας.

Δείγμα 4: Κλήση μιας μεθόδου γίνεται ασύγχρονα χρησιμοποιώντας το μοτίβο κλήσης σταθμοσκόπησης

Σε αυτήν την ενότητα, το δείγμα ανιχνεύουν το αντικείμενο IAsyncResult για να μάθετε όταν ολοκληρωθεί η ασύγχρονη κλήση. Το αντικείμενο IAsyncResult που επιστρέφεται από BeginInvoke() έχει μια ιδιότητα IsCompleted επιστρέφει True , αφού ολοκληρωθεί η ασύγχρονη κλήση. Στη συνέχεια, μπορείτε να καλέσετε EndInvoke(). Αυτό το μοτίβο κλήσης είναι χρήσιμη, εάν η εφαρμογή σας δεν συνεχούς εργασίας που δεν θέλετε να έχουν αποκλειστεί από μια κλήση συνάρτησης μακράς διαρκείας. Μια εφαρμογή των Windows της Microsoft είναι ένα παράδειγμα. Το κύριο νήμα της εφαρμογής των Windows μπορούν να συνεχίσουν να χειριστεί εισαγωγής από το χρήστη, ενώ εκτελεί μια ασύγχρονη κλήση. Κατά διαστήματα, μπορεί να ελέγχει το IsCompleted για να δείτε αν έχει ολοκληρωθεί η κλήση. Καλεί Το EndInvoke , όταν η συνάρτηση IsCompleted αποδίδει την τιμή True. Επειδή EndInvoke() αποκλείει μέχρι να ολοκληρωθεί η ασύγχρονη λειτουργία, η εφαρμογή δεν καλέστε την έως ότου μάθει ότι η λειτουργία έχει ολοκληρωθεί.
  1. Για να προσθέσετε μια συνάρτηση με όνομα DemoPolling() στην κλάση AsyncDemo . Η συνάρτηση DemoPolling() παρουσιάζει πώς μπορείτε να καλέσετε τον πληρεξούσιο ασύγχρονα και να χρησιμοποιήσετε σταθμοσκόπησης για να δείτε αν έχει ολοκληρωθεί η διαδικασία.
    public void DemoPolling(){
    MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;
    string s ;
    int iExecThread;

    // Initiate the asynchronous call.
    IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, null, null);

    // Poll IAsyncResult.IsCompleted
    while(ar.IsCompleted == false)
    {
    Thread.Sleep (10) ; // pretend to so some useful work
    }
    s = dlgt.EndInvoke (out iExecThread, ar) ;

    MessageBox.Show (string.Format ("The delegate call returned the string: \"{0}\",
    and the number {1}", s, iExecThread.ToString() ) );
    }


  2. Επεξεργαστείτε τον κώδικα προέλευσης για κύρια. Αντικαταστήστε το περιεχόμενο της συνάρτησης με τον ακόλουθο κώδικα:
    static void Main(string[] args){
    AsyncDemo ad = new AsyncDemo () ;
    ad.DemoPolling () ;
    }

  3. Πιέστε το συνδυασμό πλήκτρων CTRL + F5 για να εκτελέσουν την εφαρμογή σας.

Δείγμα 5: Εκτέλεση μιας επιστροφής κλήσης όταν ολοκληρωθεί μια ασύγχρονη μέθοδο

Σε αυτήν την ενότητα, το δείγμα παρέχει έναν πληρεξούσιο επιστροφή κλήσης στη συνάρτηση BeginInvoke() που εκτελείται από το σύστημα όταν ολοκληρωθεί η ασύγχρονη κλήση. Η επιστροφή κλήσης καλεί EndInvoke() και επεξεργάζεται τα αποτελέσματα της ασύγχρονης κλήσης. Αυτό το μοτίβο κλήσης είναι χρήσιμη, εάν το νήμα που εκκινεί την ασύγχρονη κλήση δεν χρειάζεται να επεξεργαστείτε τα αποτελέσματα της κλήσης. Το σύστημα ενεργοποιεί την επιστροφή κλήσης σε ένα νήμα διαφορετικό από το νήμα προετοιμασία, όταν ολοκληρωθεί η ασύγχρονη κλήση.


Για να χρησιμοποιήσετε αυτό το μοτίβο κλήσης, πρέπει να μεταβιβάσετε έναν πληρεξούσιο του τύπου AsyncCallback ως παράμετρος για την προτελευταία της συνάρτησης BeginInvoke() . BeginInvoke() έχει επίσης μια τελική παράμετρο του πληκτρολογήστε το αντικείμενο στο οποίο μπορείτε να διαβιβάσετε οποιοδήποτε αντικείμενο. Αυτό το αντικείμενο είναι διαθέσιμη για να σας λειτουργία επιστροφής κλήσης όταν ενεργοποιείται. Είναι μια σημαντική χρήση για αυτήν την παράμετρο για να περάσει ο πληρεξούσιος που χρησιμοποιείται για να ξεκινήσει η κλήση. Η λειτουργία επιστροφής κλήσης να χρησιμοποιήσετε τη συνάρτηση EndInvoke() του αυτός ο πληρεξούσιος για να ολοκληρωθεί η κλήση. Αυτό το μοτίβο κλήσης έχει αποδειχθεί κατωτέρω.
  1. Προσθέστε ένα δύο μέθοδοι με το όνομα DemoCallback() και MyAsyncCallback() στην κλάση AsyncDemo . Η μέθοδος DemoCallback() παρουσιάζει πώς μπορείτε να καλέσετε τον πληρεξούσιο ασύγχρονα. Χρησιμοποιεί έναν πληρεξούσιο για να αναδιπλώσετε την μέθοδο MyAsyncCallback() , η οποία καλεί το σύστημα όταν ολοκληρωθεί η ασύγχρονη λειτουργία. MyAsyncCallback() κλήσεις EndInvoke().
    public void DemoCallback(){
    MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;
    string s ;
    int iExecThread;

    // Create the callback delegate.
    AsyncCallback cb = new AsyncCallback(MyAsyncCallback);

    // Initiate the Asynchronous call passing in the callback delegate
    // and the delegate object used to initiate the call.
    IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, cb, dlgt);
    }

    public void MyAsyncCallback(IAsyncResult ar)
    {
    string s ;
    int iExecThread ;

    // Because you passed your original delegate in the asyncState parameter
    // of the Begin call, you can get it back here to complete the call.
    MethodDelegate dlgt = (MethodDelegate) ar.AsyncState;

    // Complete the call.
    s = dlgt.EndInvoke (out iExecThread, ar) ;

    MessageBox.Show (string.Format ("The delegate call returned the string: \"{0}\",
    and the number {1}", s, iExecThread.ToString() ) );
    }


  2. Επεξεργαστείτε τον κώδικα προέλευσης για κύρια. Αντικαταστήστε το περιεχόμενο της συνάρτησης με τον ακόλουθο κώδικα:
    static void Main(string[] args){
    AsyncDemo ad = new AsyncDemo () ;
    ad.DemoCallback() ;
    }

  3. Πιέστε το συνδυασμό πλήκτρων CTRL + F5 για να εκτελέσουν την εφαρμογή σας.
Ιδιότητες

Αναγνωριστικό άρθρου: 315582 - Τελευταία αναθεώρηση: 21 Ιαν 2017 - Αναθεώρηση: 1

Σχόλια