Με την ασύγχρονη κλήση μιας μεθόδου Visual C#

Μεταφράσεις άρθρων Μεταφράσεις άρθρων
Αναγν. άρθρου: 315582 - Δείτε τα προϊόντα στα οποία αναφέρεται το συγκεκριμένο άρθρο.
Ανάπτυξη όλων | Σύμπτυξη όλων

Σε αυτήν τη σελίδα

Περίληψη

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

ΑΠΑΙΤΗΣΕΙΣ


Η ακόλουθη λίστα περιγράφει το συνιστώμενο υλικό, λογισμικό, υποδομή δικτύου και τα service packs που απαιτούνται:
  • Microsoft Windows 2000 or Microsoft Windows XP or Microsoft Windows Server 2003
  • Το Visual Studio .NET ή Visual Studio 2005
Αυτό το άρθρο προϋποθέτει ότι είστε εξοικειωμένοι με τα ακόλουθα θέματα:
  • Calling methods in Visual C#
  • How to use delegates

How To Make Asynchronous Calls

Asynchronous calls are made by using delegates. A delegate is an object that wraps a function. Delegates provide a synchronous function and also provide methods for calling the wrapped function asynchronously. Those methods areBeginInvoke()ANDEndInvoke(). The parameter lists of these methods vary depending on the signature of the function that the delegate wraps. Note that the Visual Studio .NET IntelliSense feature does not displayBeginInvoke()ANDEndInvoke(), so you do not see them appear in the function lists as you type.

BeginInvoke()is used to initiate the asynchronous call. It has the same parameters as the wrapped function, plus two additional parameters that will be described later in this article.BeginInvoke()returns immediately and does not wait for the asynchronous call to complete.BeginInvoke()returns anIAsyncResultObject.

Για ναEndInvoke()function is used to retrieve the results of the asynchronous call. It can be called anytime afterBeginInvoke(). If the asynchronous call has not completed yet,EndInvoke()blocks until it completes. The parameters of theEndInvoke()function includes theoutANDrefparameters that the wrapped function has, plus theIAsyncResultobject that is returned byBeginInvoke().

The following is an example of a delegate and itsBeginInvoke()ANDEndInvoke()methods:
// 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) ;
				
There are four common ways to useBeginInvoke()ANDEndInvoke()to make asynchronous calls. After you callBeginInvoke(), you can:
  • Optionally do some other work and then useEndInvoke().
  • Obtain aWaitHandlethat is provided by theIAsyncResultobject, use itsWaitOnemethod to block until theWaitHandleis signaled, and then callEndInvoke().
  • Poll theIAsyncResultobject to determine when the asynchronous call has completed, and then callEndInvoke().
  • Have the system call a callback function that you specify. This callback function callsEndInvoke()and processes the results of the asynchronous call when it completes.
The following code samples demonstrate these call patterns and contrast them with making a synchronous call by using the following function:
string LongRunningMethod (int iCallTime, out int iExecThread)
{
	Thread.Sleep (iCallTime) ;
	iExecThread = AppDomain.GetCurrentThreadId ();
	return "MyCallTime was " + iCallTime.ToString() ;
}

				
LongRunningMethod()simulates a function that runs for long time by sleeping. It returns the sleep time and the ID of the thread that executes it. If you call it asynchronously, you find that the thread ID of the executing thread is different from that of the calling thread.

The first step is to define the delegate that wraps the function:
delegate string MethodDelegate(int iCallTime, out int iExecThread)  ;
				

Sample 1: Calling A Method Synchronously

This sample demonstrates how to callLongRunningMethod()synchronously by using aMethodDelegatedelegate. The other samples contrast this by making calls asynchronously.
  1. Ξεκινήστε το Microsoft Visual Studio .NET ή Microsoft Visual Studio 2005.
  2. Create a new Visual C# Console Application project named AsyncDemo.
  3. Add a class named AsyncDemo that is defined as follows to the project in a new .cs file:
    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() ) );
    	}
    }
    					
    Later, this class demonstrates how to make asynchronous calls. Initially, however, it only contains theDemoSyncCall()method, which demonstrates how to call the delegate synchronously.
  4. Add the following code in the body of theΚύριοςfunction that Visual Studio automatically creates in your project:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoSyncCall() ;
    }
    					
  5. Press CTRL+F5 to run your application.

Sample 2: Calling A Method Asynchronously by Using theEndInvoke()Call Pattern

In this section, the sample invokes the same method asynchronously. The call pattern that is used is to callBeginInvoke, do some work on the main thread, and then callEndInvoke(). Έχετε υπόψη ότιEndInvoke()does not return until the asynchronous call has completed. This call pattern is useful when you want to have the calling thread do work at the same time that the asynchronous call is executing. Having work occur at the same time can improve the performance of many applications. Common tasks to run asynchronously in this way are file or network operations.
  1. Add a method namedDemoEndInvoke()Για να τοAsyncDemoCLASS. Για ναDemoEndInvokefunction demonstrates how to call the delegate asynchronously.
    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. Edit the source code forΚύριοςso that it contains the following code:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoEndInvoke() ;
    }
    					
  3. Press CTRL+F5 to run your application.

Sample 3: Calling A Method Asynchronously And Using A WaitHandle To Wait For The Call To Complete


In this section, the sample calls the method asynchronously and waits for aWaitHandlebefore it callsEndInvoke(). Για ναIAsyncResultthat is returned byBeginInvoke()has anAsyncWaitHandleΙδιότητα. This property returns aWaitHandlethat is signaled when the asynchronous call completes. Waiting on aWaitHandleis a common thread synchronization technique. The calling thread waits on theWaitHandleby using theWaitOne()η μέθοδος τουWaitHandle.WaitOne()blocks until theWaitHandleis signaled. WhenWaitOne()returns, you can do some additional work before you callEndInvoke(). As in the previous sample, this technique is useful for executing file or network operations that would otherwise block the calling main thread.
  1. Add a function namedDemoWaitHandle()Για να τοAsyncDemoCLASS. Για ναDemoWaitHandle()function demonstrates how to call the delegate asynchronously.
    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. Edit the source code forΚύριοςso that it contains the following code:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoWaitHandle () ;
    }
    					
  3. Press CTRL+F5 to run your application.

Sample 4: Calling A Method Asynchronously by Using the Polling Call Pattern

In this section, the sample polls theIAsyncResultobject to find out when the asynchronous call has completed. Για ναIAsyncResultobject that is returned byBeginInvoke()has anIsCompletedproperty that returnsTrueΑφού ολοκληρωθεί η ασύγχρονη κλήση. Μπορείτε να καλέσετεEndInvoke(). Αυτό το μοτίβο κλήσης είναι χρήσιμη, εάν η εφαρμογή σας δεν βρίσκονται σε εξέλιξη εργασίας που δεν θέλετε να έχουν αποκλειστεί από μια κλήση συνάρτησης μακράς διαρκείας. Μια εφαρμογή των Microsoft Windows είναι ένα παράδειγμα. Το κύριο νήμα της εφαρμογής των Windows μπορούν να συνεχίσουν να χειριστεί παρέμβαση του χρήστη, ενώ εκτελείται μια ασύγχρονη κλήση. It can periodically checkIsCompletedto see if the call has completed. ΚαλείEndInvokewhenIsCompletedreturnsTrue. becauseEndInvoke()blocks until the asynchronous operation is complete, the application does not call it until it knows that the operation is complete.
  1. Add a function namedDemoPolling()Για να τοAsyncDemoCLASS. Για ναDemoPolling()function demonstrates how to call the delegate asynchronously and use polling to see if the process is complete.
    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. Edit the source code forΚύριος. Replace the content of the function with the following code:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoPolling () ;
    }
    					
  3. Press CTRL+F5 to run your application.

Sample 5: Executing a Callback When an Asynchronous Method Completes

In this section, the sample provides a callback delegate to theBeginInvoke()function that the system executes when the asynchronous call completes. The callback callsEndInvoke()and processes the results of the asynchronous call. This call pattern is useful if the thread that initiates the asynchronous call does not need to process the results of the call. The system invokes the callback on a thread other than the initiating thread when the asynchronous call completes.

To use this call pattern, you must pass a delegate of typeAsyncCallbackas the second-to-last parameter of theBeginInvoke()Function.BeginInvoke()also has a final parameter of typeObjectinto which you can pass any object. This object is available to your callback function when it is invoked. One important use for this parameter is to pass the delegate that is used to initiate the call. The callback function can then use theEndInvoke()function of that delegate to complete the call. This call pattern is demonstrated below.
  1. Add a two methods namedDemoCallback()ANDMyAsyncCallback()Για να τοAsyncDemoCLASS. Για ναDemoCallback()method demonstrates how to call the delegate asynchronously. It uses a delegate to wrap theMyAsyncCallback()method, which the system calls when the asynchronous operation completes.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. Edit the source code forΚύριος. Replace the content of the function with the following code:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoCallback() ;
    }
    					
  3. Press CTRL+F5 to run your application.

Ιδιότητες

Αναγν. άρθρου: 315582 - Τελευταία αναθεώρηση: Τρίτη, 21 Δεκεμβρίου 2010 - Αναθεώρηση: 2.0
Οι πληροφορίες σε αυτό το άρθρο ισχύουν για:
  • Microsoft Visual Studio .NET 2002 Professional Edition
  • Microsoft Visual C# .NET 2002 Standard Edition
  • Microsoft Visual C# 2005 Express Edition
Λέξεις-κλειδιά: 
kbhowtomaster kbmt KB315582 KbMtel
Μηχανικά μεταφρασμένο
ΣΗΜΑΝΤΙΚΟ: Αυτό το άρθρο είναι προϊόν λογισμικού μηχανικής μετάφρασης της Microsoft και όχι ανθρώπινης μετάφρασης. Η Microsoft σάς προσφέρει άρθρα που είναι προϊόντα ανθρώπινης αλλά και μηχανικής μετάφρασης έτσι ώστε να έχετε πρόσβαση σε όλα τα άρθρα της Γνωσιακής Βάσης μας στη δική σας γλώσσα. Ωστόσο, ένα άρθρο που έχει προκύψει από μηχανική μετάφραση δεν είναι πάντα άριστης ποιότητας. Ενδέχεται να περιέχει λεξιλογικά, συντακτικά ή γραμματικά λάθη, όπως ακριβώς τα λάθη που θα έκανε ένας μη φυσικός ομιλητής επιχειρώντας να μιλήσει τη γλώσσα σας. Η Microsoft δεν φέρει καμία ευθύνη για τυχόν ανακρίβειες, σφάλματα ή ζημίες που προκύψουν λόγω τυχόν παρερμηνειών στη μετάφραση του περιεχομένου ή χρήσης του από τους πελάτες της. Επίσης, η Microsoft πραγματοποιεί συχνά ενημερώσεις στο λογισμικό μηχανικής μετάφρασης.
Η αγγλική έκδοση αυτού του άρθρου είναι η ακόλουθη:315582

Αποστολή σχολίων

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com