Asynchrones Aufrufen von synchronen MethodenCalling Synchronous Methods Asynchronously

.NET Framework ermöglicht es, jede Methode auch asynchron aufzurufen.The .NET Framework enables you to call any method asynchronously. Hierzu definieren Sie einen Delegaten mit der gleichen Signatur wie die Methode, die Sie aufrufen möchten. Die Common Language Runtime definiert für diesen Delegaten automatisch eine BeginInvoke -Methode und eine EndInvoke -Methode mit den entsprechenden Signaturen.To do this you define a delegate with the same signature as the method you want to call; the common language runtime automatically defines BeginInvoke and EndInvoke methods for this delegate, with the appropriate signatures.

Hinweis

Asynchrone Delegatenaufrufe, insbesondere der BeginInvoke -Methode und der EndInvoke -Methode, werden im .NET Compact Framework nicht unterstützt.Asynchronous delegate calls, specifically the BeginInvoke and EndInvoke methods, are not supported in the .NET Compact Framework.

Die BeginInvoke -Methode initiiert den asynchronen Aufruf.The BeginInvoke method initiates the asynchronous call. Diese Methode hat die gleichen Parameter wie die Methode, die Sie asynchron ausführen möchten, inklusive zweier zusätzlicher Parameter, die optional sind.It has the same parameters as the method that you want to execute asynchronously, plus two additional optional parameters. Der erste Parameter ist ein AsyncCallback -Delegat, der auf eine Methode verweist, die bei Beendigung des asynchronen Aufrufs aufzurufen ist.The first parameter is an AsyncCallback delegate that references a method to be called when the asynchronous call completes. Der zweite Parameter ist ein benutzerdefiniertes Objekt, das Informationen an die Rückrufmethode übergibt.The second parameter is a user-defined object that passes information into the callback method. BeginInvoke wird immer sofort zurückgegeben und wartet nicht, bis der asynchrone Aufruf abgeschlossen wurde.BeginInvoke returns immediately and does not wait for the asynchronous call to complete. BeginInvoke gibt ein IAsyncResultzurück, mit dem der Status des asynchronen Aufrufs überwacht werden kann.BeginInvoke returns an IAsyncResult, which can be used to monitor the progress of the asynchronous call.

Die Ergebnisse dieses asynchronen Aufrufs werden dann mithilfe der EndInvoke -Methode abgerufen.The EndInvoke method retrieves the results of the asynchronous call. Diese kann jederzeit nach der BeginInvoke-Methode aufgerufen werden.It can be called any time after BeginInvoke. Wenn der asynchrone Aufruf nicht abgeschlossen wurde, blockiert EndInvoke den aufrufenden Thread, bis er abgeschlossen ist.If the asynchronous call has not completed, EndInvoke blocks the calling thread until it completes. Zu den Parametern von EndInvoke gehören der out -Methode und eine ref -Parameter (<Out> ByRef -Methode und eine ByRef in Visual Basic) der Methode, die asynchron ausgeführt werden soll, sowie das IAsyncResult , das von BeginInvoke-Methode aufgerufen werden.The parameters of EndInvoke include the out and ref parameters (<Out> ByRef and ByRef in Visual Basic) of the method that you want to execute asynchronously, plus the IAsyncResult returned by BeginInvoke.

Hinweis

Das IntelliSense-Feature in Visual Studio 2005Visual Studio 2005 zeigt die Parameter von BeginInvoke und EndInvokean.The IntelliSense feature in Visual Studio 2005Visual Studio 2005 displays the parameters of BeginInvoke and EndInvoke. Sofern Sie nicht Visual Studio oder ein vergleichbares Tool verwenden, oder wenn Sie C# zusammen mit Visual Studio 2005Visual Studio 2005 nutzen, finden Sie unter Asynchronous Programming Model (APM) (Asychrones Programmiermodell (APM)) eine Beschreibung der für diese Methoden festgelegten Parameter.If you are not using Visual Studio or a similar tool, or if you are using C# with Visual Studio 2005Visual Studio 2005, see Asynchronous Programming Model (APM) for a description of the parameters defined for these methods.

Die in diesem Abschnitt verwendeten Codebeispiele veranschaulichen die vier gebräuchlichen Arten der Verwendung von BeginInvoke und EndInvoke bei asynchronen Aufrufen.The code examples in this topic demonstrate four common ways to use BeginInvoke and EndInvoke to make asynchronous calls. Nach dem Aufrufen von BeginInvoke können Sie Folgendes tun:After calling BeginInvoke you can do the following:

  • Sie können etwas Arbeit erledigen und dann EndInvoke aufrufen, um eine Blockierung bis zum Abschluss des Aufrufs zu erreichen.Do some work and then call EndInvoke to block until the call completes.

  • Rufen Sie ein WaitHandle mithilfe der IAsyncResult.AsyncWaitHandle-Eigenschaft ab. Verwenden Sie deren WaitOne-Methode, um die Ausführung zu blockieren, bis das WaitHandle signalisiert wurde, und rufen Sie dann EndInvoke auf.Obtain a WaitHandle using the IAsyncResult.AsyncWaitHandle property, use its WaitOne method to block execution until the WaitHandle is signaled, and then call EndInvoke.

  • Sie können das von IAsyncResult zurückgegebene BeginInvoke abrufen, um zu ermitteln, wann der asynchrone Aufruf beendet wurde, und dann EndInvokeabrufen.Poll the IAsyncResult returned by BeginInvoke to determine when the asynchronous call has completed, and then call EndInvoke.

  • Sie können einen Delegaten für eine Rückrufmethode an BeginInvoke übergeben.Pass a delegate for a callback method to BeginInvoke. Die Methode wird bei Beendigung des asynchronen Aufrufs für einen ThreadPool -Thread ausgeführt.The method is executed on a ThreadPool thread when the asynchronous call completes. Die Rückrufmethode ruft die EndInvoke-Methode auf.The callback method calls EndInvoke.

Wichtig

Unabhängig von der Vorgehensweise wird immer EndInvoke aufgerufen, um den asynchronen Aufruf abzuschließen.No matter which technique you use, always call EndInvoke to complete your asynchronous call.

Definieren der Testmethode und des asynchronen DelegatenDefining the Test Method and Asynchronous Delegate

In den folgenden Codebeispielen werden verschiedene Möglichkeiten veranschaulicht, wie die gleiche zeitintensive Methode, TestMethod, asynchron aufgerufen werden kann.The code examples that follow demonstrate various ways of calling the same long-running method, TestMethod, asynchronously. Die TestMethod -Methode zeigt eine Konsolenmeldung an, um zu zeigen, dass mit der Verarbeitung begonnen wurde, wechselt für einige Sekunden in den Ruhezustand und wird dann beendet.The TestMethod method displays a console message to show that it has begun processing, sleeps for a few seconds, and then ends. TestMethod verfügt über einen out -Parameter, um zu zeigen, wie solche Parameter zu den Signaturen von BeginInvoke und EndInvokehinzugefügt werden.TestMethod has an out parameter to demonstrate the way such parameters are added to the signatures of BeginInvoke and EndInvoke. Sie können ref -Parameter auf ähnliche Weise behandeln.You can handle ref parameters similarly.

Im folgenden Codebeispiel werden die Definitionen von TestMethod und des Delegaten mit dem Namen AsyncMethodCaller veranschaulicht, die beide zum asynchronen Aufrufen von TestMethod verwendet werden können.The following code example shows the definition of TestMethod and the delegate named AsyncMethodCaller that can be used to call TestMethod asynchronously. Beim Kompilieren der Codebeispiele müssen Sie die Definitionen für TestMethod und für den AsyncMethodCaller -Delegaten hinzufügen.To compile the code examples, you must include the definitions for TestMethod and the AsyncMethodCaller delegate.

using namespace System;
using namespace System::Threading;
using namespace System::Runtime::InteropServices; 

namespace Examples {
namespace AdvancedProgramming {
namespace AsynchronousOperations
{
    public ref class AsyncDemo 
    {
    public:
        // The method to be executed asynchronously.
        String^ TestMethod(int callDuration, [OutAttribute] int% threadId) 
        {
            Console::WriteLine("Test method begins.");
            Thread::Sleep(callDuration);
            threadId = Thread::CurrentThread->ManagedThreadId;
            return String::Format("My call time was {0}.", callDuration);
        }
    };

    // The delegate must have the same signature as the method
    // it will call asynchronously.
    public delegate String^ AsyncMethodCaller(int callDuration, [OutAttribute] int% threadId);
}}}
using System;
using System.Threading; 

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
    public class AsyncDemo 
    {
        // The method to be executed asynchronously.
        public string TestMethod(int callDuration, out int threadId) 
        {
            Console.WriteLine("Test method begins.");
            Thread.Sleep(callDuration);
            threadId = Thread.CurrentThread.ManagedThreadId;
            return String.Format("My call time was {0}.", callDuration.ToString());
        }
    }
    // The delegate must have the same signature as the method
    // it will call asynchronously.
    public delegate string AsyncMethodCaller(int callDuration, out int threadId);
}
Imports System
Imports System.Threading
Imports System.Runtime.InteropServices 

Namespace Examples.AdvancedProgramming.AsynchronousOperations
    Public Class AsyncDemo 
        ' The method to be executed asynchronously.
        Public Function TestMethod(ByVal callDuration As Integer, _
                <Out> ByRef threadId As Integer) As String
            Console.WriteLine("Test method begins.")
            Thread.Sleep(callDuration)
            threadId = Thread.CurrentThread.ManagedThreadId()
            return String.Format("My call time was {0}.", callDuration.ToString())
        End Function
    End Class

    ' The delegate must have the same signature as the method
    ' it will call asynchronously.
    Public Delegate Function AsyncMethodCaller(ByVal callDuration As Integer, _
        <Out> ByRef threadId As Integer) As String
End Namespace

Warten auf einen asynchronen Aufruf mit "EndInvoke"Waiting for an Asynchronous Call with EndInvoke

Die einfachste Möglichkeit zum asynchronen Ausführen einer Methode besteht darin, das Ausführen der Methode durch Aufrufen der BeginInvoke -Methode des Delegaten zu starten, einige Aufgaben im Hauptthread auszuführen und dann die EndInvoke -Methode des Delegaten aufzurufen.The simplest way to execute a method asynchronously is to start executing the method by calling the delegate's BeginInvoke method, do some work on the main thread, and then call the delegate's EndInvoke method. EndInvoke kann den aufrufenden Thread blockieren, da dies erst zurückgegeben wird, wenn der asynchrone Aufruf abgeschlossen wurde.EndInvoke might block the calling thread because it does not return until the asynchronous call completes. Dies ist ein gutes Verfahren für Datei- oder Netzwerkvorgänge.This is a good technique to use with file or network operations.

Wichtig

Da EndInvoke blockieren kann, sollte sie nicht aus Threads für die Benutzeroberfläche aufgerufen werden.Because EndInvoke might block, you should never call it from threads that service the user interface.

#using <TestMethod.dll>

using namespace System;
using namespace System::Threading;
using namespace Examples::AdvancedProgramming::AsynchronousOperations;

void main() 
{
    // The asynchronous method puts the thread id here.
    int threadId = 2546;

    // Create an instance of the test class.
    AsyncDemo^ ad = gcnew AsyncDemo();

    // Create the delegate.
    AsyncMethodCaller^ caller = gcnew AsyncMethodCaller(ad, &AsyncDemo::TestMethod);
       
    // Initiate the asychronous call.
    IAsyncResult^ result = caller->BeginInvoke(3000, 
        threadId, nullptr, nullptr);

    Thread::Sleep(1);
    Console::WriteLine("Main thread {0} does some work.",
        Thread::CurrentThread->ManagedThreadId);

    // Call EndInvoke to wait for the asynchronous call to complete,
    // and to retrieve the results.
    String^ returnValue = caller->EndInvoke(threadId, result);

    Console::WriteLine("The call executed on thread {0}, with return value \"{1}\".",
        threadId, returnValue);
}

/* This example produces output similar to the following:

Main thread 1 does some work.
Test method begins.
The call executed on thread 3, with return value "My call time was 3000.".
 */
using System;
using System.Threading;

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
    public class AsyncMain 
    {
        public static void Main() 
        {
            // The asynchronous method puts the thread id here.
            int threadId;

            // Create an instance of the test class.
            AsyncDemo ad = new AsyncDemo();

            // Create the delegate.
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
       
            // Initiate the asychronous call.
            IAsyncResult result = caller.BeginInvoke(3000, 
                out threadId, null, null);

            Thread.Sleep(0);
            Console.WriteLine("Main thread {0} does some work.",
                Thread.CurrentThread.ManagedThreadId);

            // Call EndInvoke to wait for the asynchronous call to complete,
            // and to retrieve the results.
            string returnValue = caller.EndInvoke(out threadId, result);

            Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",
                threadId, returnValue);
        }
    }
}

/* This example produces output similar to the following:

Main thread 1 does some work.
Test method begins.
The call executed on thread 3, with return value "My call time was 3000.".
 */
Imports System
Imports System.Threading
Imports System.Runtime.InteropServices 

Namespace Examples.AdvancedProgramming.AsynchronousOperations
    Public Class AsyncMain 
        Shared Sub Main() 
            ' The asynchronous method puts the thread id here.
            Dim threadId As Integer

            ' Create an instance of the test class.
            Dim ad As New AsyncDemo()

            ' Create the delegate.
            Dim caller As New AsyncMethodCaller(AddressOf ad.TestMethod)
       
            ' Initiate the asynchronous call.
            Dim result As IAsyncResult = caller.BeginInvoke(3000, _
                threadId, Nothing, Nothing)

            Thread.Sleep(0)
            Console.WriteLine("Main thread {0} does some work.", _
                 Thread.CurrentThread.ManagedThreadId)

            ' Call EndInvoke to Wait for the asynchronous call to complete,
            ' and to retrieve the results.
            Dim returnValue As String = caller.EndInvoke(threadId, result)

            Console.WriteLine("The call executed on thread {0}, with return value ""{1}"".", _
                threadId, returnValue)
        End Sub
    End Class

End Namespace

'This example produces output similar to the following:
'
'Main thread 1 does some work.
'Test method begins.
'The call executed on thread 3, with return value "My call time was 3000.".

Warten auf einen asynchronen Aufruf mit "WaitHandle"Waiting for an Asynchronous Call with WaitHandle

Sie können ein WaitHandle mithilfe der AsyncWaitHandle -Eigenschaft vom IAsyncResult abrufen, das von BeginInvokezurückgegeben wird.You can obtain a WaitHandle by using the AsyncWaitHandle property of the IAsyncResult returned by BeginInvoke. Das WaitHandle wird bei Beendigung des asynchronen Aufrufs signalisiert, und durch Aufrufen der WaitOne -Methode kann darauf gewartet werden.The WaitHandle is signaled when the asynchronous call completes, and you can wait for it by calling the WaitOne method.

Bei Verwendung eines WaitHandlekann vor oder nach Abschluss des asynchronen Aufrufs eine weitere Verarbeitung erfolgen. Dies ist jedoch nur vor dem Abrufen der Ergebnisse über den Aufruf von EndInvoke möglich.If you use a WaitHandle, you can perform additional processing before or after the asynchronous call completes, but before calling EndInvoke to retrieve the results.

Hinweis

Das Wait-Handle wird nicht automatisch geschlossen, wenn Sie EndInvoke aufrufen.The wait handle is not closed automatically when you call EndInvoke. Wenn Sie alle Verweise auf das Wait-Handle freigeben, werden Systemressourcen frei, sobald das Wait-Handle von der Garbage Collection zurückgefordert wird.If you release all references to the wait handle, system resources are freed when garbage collection reclaims the wait handle. Um die Systemressourcen unmittelbar nach der Verwendung des Wait-Handles freizugeben, löschen Sie es, indem Sie die WaitHandle.Close-Methode aufrufen.To free the system resources as soon as you are finished using the wait handle, dispose of it by calling the WaitHandle.Close method. Garbage Collection arbeitet effizienter, wenn verwerfbare Objekte explizit entfernt werden.Garbage collection works more efficiently when disposable objects are explicitly disposed.

#using <TestMethod.dll>

using namespace System;
using namespace System::Threading;
using namespace Examples::AdvancedProgramming::AsynchronousOperations;

void main() 
{
    // The asynchronous method puts the thread id here.
    int threadId;

    // Create an instance of the test class.
    AsyncDemo^ ad = gcnew AsyncDemo();

    // Create the delegate.
    AsyncMethodCaller^ caller = gcnew AsyncMethodCaller(ad, &AsyncDemo::TestMethod);
       
    // Initiate the asychronous call.
    IAsyncResult^ result = caller->BeginInvoke(3000, 
        threadId, nullptr, nullptr);

    Thread::Sleep(0);
    Console::WriteLine("Main thread {0} does some work.",
        Thread::CurrentThread->ManagedThreadId);

    // Wait for the WaitHandle to become signaled.
    result->AsyncWaitHandle->WaitOne();

    // Perform additional processing here.
    // Call EndInvoke to retrieve the results.
    String^ returnValue = caller->EndInvoke(threadId, result);

    // Close the wait handle.
    result->AsyncWaitHandle->Close();

    Console::WriteLine("The call executed on thread {0}, with return value \"{1}\".",
        threadId, returnValue);
}

/* This example produces output similar to the following:

Main thread 1 does some work.
Test method begins.
The call executed on thread 3, with return value "My call time was 3000.".
 */
using System;
using System.Threading;

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
    public class AsyncMain 
    {
        static void Main() 
        {
            // The asynchronous method puts the thread id here.
            int threadId;

            // Create an instance of the test class.
            AsyncDemo ad = new AsyncDemo();

            // Create the delegate.
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
       
            // Initiate the asychronous call.
            IAsyncResult result = caller.BeginInvoke(3000, 
                out threadId, null, null);

            Thread.Sleep(0);
            Console.WriteLine("Main thread {0} does some work.",
                Thread.CurrentThread.ManagedThreadId);

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

            // Perform additional processing here.
            // Call EndInvoke to retrieve the results.
            string returnValue = caller.EndInvoke(out threadId, result);

            // Close the wait handle.
            result.AsyncWaitHandle.Close();

            Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",
                threadId, returnValue);
        }
    }
}

/* This example produces output similar to the following:

Main thread 1 does some work.
Test method begins.
The call executed on thread 3, with return value "My call time was 3000.".
 */
Imports System
Imports System.Threading
Imports System.Runtime.InteropServices 

Namespace Examples.AdvancedProgramming.AsynchronousOperations

    Public Class AsyncMain 
        Shared Sub Main() 
            ' The asynchronous method puts the thread id here.
            Dim threadId As Integer

            ' Create an instance of the test class.
            Dim ad As New AsyncDemo()

            ' Create the delegate.
            Dim caller As New AsyncMethodCaller(AddressOf ad.TestMethod)
       
            ' Initiate the asynchronous call.
            Dim result As IAsyncResult = caller.BeginInvoke(3000, _
                threadId, Nothing, Nothing)

            Thread.Sleep(0)
            Console.WriteLine("Main thread {0} does some work.", _
                Thread.CurrentThread.ManagedThreadId)
            ' Perform additional processing here and then
            ' wait for the WaitHandle to be signaled.
            result.AsyncWaitHandle.WaitOne()

            ' Call EndInvoke to retrieve the results.
            Dim returnValue As String = caller.EndInvoke(threadId, result)

            ' Close the wait handle.
            result.AsyncWaitHandle.Close()

            Console.WriteLine("The call executed on thread {0}, with return value ""{1}"".", _
                threadId, returnValue)
        End Sub
    End Class
End Namespace

'This example produces output similar to the following:
'
'Main thread 1 does some work.
'Test method begins.
'The call executed on thread 3, with return value "My call time was 3000.".

Abrufen der asynchronen AufrufbeendigungPolling for Asynchronous Call Completion

Mit der IsCompleted -Eigenschaft des von IAsyncResult zurückgegebenen BeginInvoke können Sie feststellen, wann der asynchrone Aufruf abgeschlossen wird.You can use the IsCompleted property of the IAsyncResult returned by BeginInvoke to discover when the asynchronous call completes. Dieses Verfahren ist empfehlenswert, wenn der asynchrone Aufruf aus einem Thread für die Benutzeroberfläche erfolgt.You might do this when making the asynchronous call from a thread that services the user interface. Durch das Abrufen der Beendigung kann die Verarbeitung vom aufrufenden Thread fortgesetzt werden, während der asynchrone Aufruf für einen ThreadPool -Thread ausgeführt wird.Polling for completion allows the calling thread to continue executing while the asynchronous call executes on a ThreadPool thread.

#using <TestMethod.dll>

using namespace System;
using namespace System::Threading;
using namespace Examples::AdvancedProgramming::AsynchronousOperations;

void main() 
{
    // The asynchronous method puts the thread id here.
    int threadId;

    // Create an instance of the test class.
    AsyncDemo^ ad = gcnew AsyncDemo();

    // Create the delegate.
    AsyncMethodCaller^ caller = gcnew AsyncMethodCaller(ad, &AsyncDemo::TestMethod);
       
    // Initiate the asychronous call.
    IAsyncResult^ result = caller->BeginInvoke(3000, 
        threadId, nullptr, nullptr);

    // Poll while simulating work.
    while(result->IsCompleted == false)
    {
        Thread::Sleep(250);
        Console::Write(".");
    }

    // Call EndInvoke to retrieve the results.
    String^ returnValue = caller->EndInvoke(threadId, result);

    Console::WriteLine("\nThe call executed on thread {0}, with return value \"{1}\".",
        threadId, returnValue);
}

/* This example produces output similar to the following:

Test method begins.
.............
The call executed on thread 3, with return value "My call time was 3000.".
 */
using System;
using System.Threading;

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
    public class AsyncMain 
    {
        static void Main() {
            // The asynchronous method puts the thread id here.
            int threadId;

            // Create an instance of the test class.
            AsyncDemo ad = new AsyncDemo();

            // Create the delegate.
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
       
            // Initiate the asychronous call.
            IAsyncResult result = caller.BeginInvoke(3000, 
                out threadId, null, null);

            // Poll while simulating work.
            while(result.IsCompleted == false) {
                Thread.Sleep(250);
                Console.Write(".");
            }

            // Call EndInvoke to retrieve the results.
            string returnValue = caller.EndInvoke(out threadId, result);

            Console.WriteLine("\nThe call executed on thread {0}, with return value \"{1}\".",
                threadId, returnValue);
        }
    }
}

/* This example produces output similar to the following:

Test method begins.
.............
The call executed on thread 3, with return value "My call time was 3000.".
 */
Imports System
Imports System.Threading
Imports System.Runtime.InteropServices 

Namespace Examples.AdvancedProgramming.AsynchronousOperations

    Public Class AsyncMain 
        Shared Sub Main() 
            ' The asynchronous method puts the thread id here.
            Dim threadId As Integer

            ' Create an instance of the test class.
            Dim ad As New AsyncDemo()

            ' Create the delegate.
            Dim caller As New AsyncMethodCaller(AddressOf ad.TestMethod)
       
            ' Initiate the asynchronous call.
            Dim result As IAsyncResult = caller.BeginInvoke(3000, _
                threadId, Nothing, Nothing)

            ' Poll while simulating work.
            While result.IsCompleted = False
                Thread.Sleep(250)
                Console.Write(".")
            End While

            ' Call EndInvoke to retrieve the results.
            Dim returnValue As String = caller.EndInvoke(threadId, result)

            Console.WriteLine(vbCrLf & _
                "The call executed on thread {0}, with return value ""{1}"".", _
                threadId, returnValue)
        End Sub
    End Class
End Namespace

' This example produces output similar to the following:
'
'Test method begins.
'.............
'The call executed on thread 3, with return value "My call time was 3000.".

Ausführen einer Rückrufmethode bei Beendigung eines asynchronen AufrufsExecuting a Callback Method When an Asynchronous Call Completes

Wenn der Thread, der den asynchronen Aufruf gestartet hat, die Ergebnisse nicht verarbeiten muss, können Sie bei Beendigung des Aufrufs eine Rückrufmethode ausführen.If the thread that initiates the asynchronous call does not need to be the thread that processes the results, you can execute a callback method when the call completes. Die Rückrufmethode wird auf einem ThreadPool -Thread ausgeführt.The callback method is executed on a ThreadPool thread.

Um eine Rückrufmethode verwenden zu können, müssen Sie BeginInvoke an einen AsyncCallback -Delegaten übergeben, der die Rückrufmethode darstellt.To use a callback method, you must pass BeginInvoke an AsyncCallback delegate that represents the callback method. Sie können auch ein Objekt übergeben, das die von der Rückrufmethode zu verwendenden Informationen enthält.You can also pass an object that contains information to be used by the callback method. Mit der Rückrufmethode können Sie das IAsyncResult, das den einzigen Parameter der Rückrufmethode darstellt, in ein AsyncResult -Objekt umwandeln.In the callback method, you can cast the IAsyncResult, which is the only parameter of the callback method, to an AsyncResult object. Mithilfe der AsyncResult.AsyncDelegate-Eigenschaft erhalten Sie dann den Delegaten, der zur Initiierung des Aufrufs verwendet wurde, sodass Sie EndInvoke aufrufen können.You can then use the AsyncResult.AsyncDelegate property to get the delegate that was used to initiate the call so that you can call EndInvoke.

Hinweise zum Beispiel:Notes on the example:

  • Der threadId-Parameter von TestMethod ist ein out-Parameter ([<Out> ByRef in Visual Basic). Deshalb wird sein Eingabewert niemals von TestMethod verwendet.The threadId parameter of TestMethod is an out parameter ([<Out> ByRef in Visual Basic), so its input value is never used by TestMethod. Eine Dummyvariable wird an den BeginInvoke -Aufruf übergeben.A dummy variable is passed to the BeginInvoke call. Wenn der threadId -Parameter ein ref -Parameter wäre (ByRef in Visual Basic), müsste die Variable ein Feld auf Klassenebene darstellen, damit sie sowohl an BeginInvoke als auch an EndInvokeübergeben werden könnte.If the threadId parameter were a ref parameter (ByRef in Visual Basic), the variable would have to be a class-level field so that it could be passed to both BeginInvoke and EndInvoke.

  • Die an BeginInvoke übergebenen Zustandsinformationen bestehen aus einer Formatzeichenfolge, die von der Rückrufmethode zum Formatieren einer Ausgabemeldung verwendet wird.The state information that is passed to BeginInvoke is a format string, which the callback method uses to format an output message. Da sie als Object-Typ übergeben werden, müssen die Zustandsinformationen vor der Verwendung in den geeigneten Typ umgewandelt werden.Because it is passed as type Object, the state information must be cast to its proper type before it can be used.

  • Der Rückruf erfolgt in einem ThreadPool -Thread.The callback is made on a ThreadPool thread. ThreadPool -Threads sind Hintergrundthreads, die nicht dafür sorgen, dass die Anwendung weiter ausgeführt wird, wenn der Hauptthread beendet wird. Aus diesem Grund muss der Hauptthread des Beispiels im Ruhezustand verbleiben, bis der Rückruf abgeschlossen ist.ThreadPool threads are background threads, which do not keep the application running if the main thread ends, so the main thread of the example has to sleep long enough for the callback to finish.

#using <TestMethod.dll>

using namespace System;
using namespace System::Threading;
using namespace System::Runtime::Remoting::Messaging;
using namespace Examples::AdvancedProgramming::AsynchronousOperations;

// The callback method must have the same signature as the
// AsyncCallback delegate.
void CallbackMethod(IAsyncResult^ ar) 
{
    // Retrieve the delegate.
    AsyncResult^ result = (AsyncResult^) ar;
    AsyncMethodCaller^ caller = (AsyncMethodCaller^) result->AsyncDelegate;

    // Retrieve the format string that was passed as state 
    // information.
    String^ formatString = (String^) ar->AsyncState;

    // Define a variable to receive the value of the out parameter.
    // If the parameter were ref rather than out then it would have to
    // be a class-level field so it could also be passed to BeginInvoke.
    int threadId = 0;

    // Call EndInvoke to retrieve the results.
    String^ returnValue = caller->EndInvoke(threadId, ar);

    // Use the format string to format the output message.
    Console::WriteLine(formatString, threadId, returnValue);
};

void main() 
{
    // Create an instance of the test class.
    AsyncDemo^ ad = gcnew AsyncDemo();

    // Create the delegate.
    AsyncMethodCaller^ caller = gcnew AsyncMethodCaller(ad, &AsyncDemo::TestMethod);
       
    // The threadId parameter of TestMethod is an out parameter, so
    // its input value is never used by TestMethod. Therefore, a dummy
    // variable can be passed to the BeginInvoke call. If the threadId
    // parameter were a ref parameter, it would have to be a class-
    // level field so that it could be passed to both BeginInvoke and 
    // EndInvoke.
    int dummy = 0;

    // Initiate the asynchronous call, passing three seconds (3000 ms)
    // for the callDuration parameter of TestMethod; a dummy variable 
    // for the out parameter (threadId); the callback delegate; and
    // state information that can be retrieved by the callback method.
    // In this case, the state information is a string that can be used
    // to format a console message.
    IAsyncResult^ result = caller->BeginInvoke(3000,
        dummy, 
        gcnew AsyncCallback(&CallbackMethod),
        "The call executed on thread {0}, with return value \"{1}\".");

    Console::WriteLine("The main thread {0} continues to execute...", 
        Thread::CurrentThread->ManagedThreadId);

    // The callback is made on a ThreadPool thread. ThreadPool threads
    // are background threads, which do not keep the application running
    // if the main thread ends. Comment out the next line to demonstrate
    // this.
    Thread::Sleep(4000);
    Console::WriteLine("The main thread ends.");
}

/* This example produces output similar to the following:

The main thread 1 continues to execute...
Test method begins.
The call executed on thread 3, with return value "My call time was 3000.".
The main thread ends.
 */
using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
    public class AsyncMain 
    {
        static void Main() 
        {
            // Create an instance of the test class.
            AsyncDemo ad = new AsyncDemo();

            // Create the delegate.
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
       
            // The threadId parameter of TestMethod is an out parameter, so
            // its input value is never used by TestMethod. Therefore, a dummy
            // variable can be passed to the BeginInvoke call. If the threadId
            // parameter were a ref parameter, it would have to be a class-
            // level field so that it could be passed to both BeginInvoke and 
            // EndInvoke.
            int dummy = 0;

            // Initiate the asynchronous call, passing three seconds (3000 ms)
            // for the callDuration parameter of TestMethod; a dummy variable 
            // for the out parameter (threadId); the callback delegate; and
            // state information that can be retrieved by the callback method.
            // In this case, the state information is a string that can be used
            // to format a console message.
            IAsyncResult result = caller.BeginInvoke(3000,
                out dummy, 
                new AsyncCallback(CallbackMethod),
                "The call executed on thread {0}, with return value \"{1}\".");

            Console.WriteLine("The main thread {0} continues to execute...", 
                Thread.CurrentThread.ManagedThreadId);

            // The callback is made on a ThreadPool thread. ThreadPool threads
            // are background threads, which do not keep the application running
            // if the main thread ends. Comment out the next line to demonstrate
            // this.
            Thread.Sleep(4000);

            Console.WriteLine("The main thread ends.");
        }
        
        // The callback method must have the same signature as the
        // AsyncCallback delegate.
        static void CallbackMethod(IAsyncResult ar) 
        {
            // Retrieve the delegate.
            AsyncResult result = (AsyncResult) ar;
            AsyncMethodCaller caller = (AsyncMethodCaller) result.AsyncDelegate;

            // Retrieve the format string that was passed as state 
            // information.
            string formatString = (string) ar.AsyncState;

            // Define a variable to receive the value of the out parameter.
            // If the parameter were ref rather than out then it would have to
            // be a class-level field so it could also be passed to BeginInvoke.
            int threadId = 0;

            // Call EndInvoke to retrieve the results.
            string returnValue = caller.EndInvoke(out threadId, ar);

            // Use the format string to format the output message.
            Console.WriteLine(formatString, threadId, returnValue);
        }
    }
}

/* This example produces output similar to the following:

The main thread 1 continues to execute...
Test method begins.
The call executed on thread 3, with return value "My call time was 3000.".
The main thread ends.
 */
Imports System
Imports System.Threading
Imports System.Runtime.Remoting.Messaging

Namespace Examples.AdvancedProgramming.AsynchronousOperations

    Public Class AsyncMain 
        
        Shared Sub Main() 

            ' Create an instance of the test class.
            Dim ad As New AsyncDemo()

            ' Create the delegate.
            Dim caller As New AsyncMethodCaller(AddressOf ad.TestMethod)

            ' The threadId parameter of TestMethod is an <Out> parameter, so
            ' its input value is never used by TestMethod. Therefore, a dummy
            ' variable can be passed to the BeginInvoke call. If the threadId
            ' parameter were a ByRef parameter, it would have to be a class-
            ' level field so that it could be passed to both BeginInvoke and 
            ' EndInvoke.
            Dim dummy As Integer = 0

            ' Initiate the asynchronous call, passing three seconds (3000 ms)
            ' for the callDuration parameter of TestMethod; a dummy variable 
            ' for the <Out> parameter (threadId); the callback delegate; and
            ' state information that can be retrieved by the callback method.
            ' In this case, the state information is a string that can be used
            ' to format a console message.
            Dim result As IAsyncResult = caller.BeginInvoke(3000, _
                dummy, _
                AddressOf CallbackMethod, _
                "The call executed on thread {0}, with return value ""{1}"".")

            Console.WriteLine("The main thread {0} continues to execute...", _
                Thread.CurrentThread.ManagedThreadId)

            ' The callback is made on a ThreadPool thread. ThreadPool threads
            ' are background threads, which do not keep the application running
            ' if the main thread ends. Comment out the next line to demonstrate
            ' this.
            Thread.Sleep(4000)

            Console.WriteLine("The main thread ends.")
        End Sub

        ' The callback method must have the same signature as the
        ' AsyncCallback delegate.
        Shared Sub CallbackMethod(ByVal ar As IAsyncResult)
            ' Retrieve the delegate.
            Dim result As AsyncResult = CType(ar, AsyncResult)
            Dim caller As AsyncMethodCaller = CType(result.AsyncDelegate, AsyncMethodCaller)

            ' Retrieve the format string that was passed as state 
            ' information.
            Dim formatString As String = CType(ar.AsyncState, String)

            ' Define a variable to receive the value of the <Out> parameter.
            ' If the parameter were ByRef rather than <Out> then it would have to
            ' be a class-level field so it could also be passed to BeginInvoke.
            Dim threadId As Integer = 0

            ' Call EndInvoke to retrieve the results.
            Dim returnValue As String = caller.EndInvoke(threadId, ar)

            ' Use the format string to format the output message.
            Console.WriteLine(formatString, threadId, returnValue)
        End Sub
    End Class
End Namespace

' This example produces output similar to the following:
'
'The main thread 1 continues to execute...
'Test method begins.
'The call executed on thread 3, with return value "My call time was 3000.".
'The main thread ends.

Siehe auchSee Also

Delegate
Ereignisbasiertes asynchrones Muster (EAP)Event-based Asynchronous Pattern (EAP)