Wie Sie eine Visual C#-Methode asynchron aufrufen

Zusammenfassung

Microsoft.NET Framework vereinfacht den asynchronen Aufruf von Funktionen. Der asynchrone Aufruf von Funktionen führt dazu, dass das System diese im Hintergrund in einem sekündären Thread ausführt, während die aufrufende Funktion weiterhin andere Arbeiten ausführt. Eine normale (synchrone) Aufruf wird die Funktion sofort im gleichen Thread ausgeführt, der den Aufruf ausgeführt hat. Die aufrufende Funktion wartet, bis der Aufruf abgeschlossen und erhält den Aufrufs bevor Sie fortfahren. Im Gegensatz dazu beim asynchron aufgerufen werden kann, rufen Sie die Ergebnisse des asynchronen Aufrufs später. Dieser Artikel beschreibt die Vorgehensweise mit Visual C#.

Voraussetzungen


Die folgende Liste führt die empfohlene Hardware, Software, Netzwerkinfrastruktur und Servicepacks auf, die benötigt werden:
  • Microsoft Windows 2000 oder Microsoft Windows XP oder Microsoft Windows Server 2003
  • Visual Studio .NET oder Visual Studio 2005
Es wird vorausgesetzt, dass Sie mit folgenden Themen vertraut sind:
  • Aufrufen von Methoden in Visual C#
  • Zum Verwenden von Delegaten

Asynchrone Aufrufe erstellen

Asynchrone Aufrufe enstehen durch sog. Delegaten. Ein Delegat ist ein Objekt, das eine Funktion umschließt. Delegaten bieten eine synchrone Funktion und auch Methoden, um die umschlossene Funktion asynchron aufzurufen. Diese Methoden sind BeginInvoke() und EndInvoke(). Die Parameterlisten der folgenden Methoden, abhängig von der Signatur der Funktion, die der Delegat umschließt. Beachten Sie, dass Visual Studio .NET IntelliSense-Feature nicht angezeigt wird, BeginInvoke() und EndInvoke()nicht angezeigt während der Eingabe in die Funktion Listen erscheinen.


BeginInvoke() wird verwendet, um den asynchronen Aufruf initiiert. Es verfügt über dieselben Parameter wie die umschlossene Funktion sowie zwei zusätzliche Parameter, die in diesem Artikel beschrieben werden. BeginInvoke() sofort zurückgegeben und wartet nicht auf den asynchronen Aufruf abzuschließen. BeginInvoke() gibt ein IAsyncResult -Objekt.

Die EndInvoke() -Funktion zum Abrufen der Ergebnisse des asynchronen Aufrufs. Sie kann jederzeit nach BeginInvoke()aufgerufen werden. Wenn der asynchrone Aufruf noch nicht, EndInvoke() Blöcke abgeschlossen hat bis zu deren Abschluss. Enthält die Parameter der Funktion EndInvoke() der , und
Ref -Parameter, die die umschlossene Funktion sowie das IAsyncResult -Objekt verfügt, das von BeginInvoke()zurückgegeben.

Das folgende ist ein Beispiel eines Delegaten und BeginInvoke() und 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) ;

Es gibt vier allgemeine Arten von BeginInvoke() und EndInvoke() zum asynchronen Aufrufen. Nach dem Aufruf von BeginInvoke()können Sie:
  • Optional leisten Sie einige andere Arbeit, und verwenden dann EndInvoke().
  • Erhalten ein WaitHandle , die das IAsyncResult -Objekt zur Verfügung, mit der zugehörigen WaitOne -Methode blockiert, bis das WaitHandle signalisiert und rufen Sie EndInvoke().
  • Abrufen Sie das IAsyncResult -Objekt zu bestimmen, wann der asynchrone Aufruf abgeschlossen wurde, rufen Sie EndInvoke().
  • Haben Sie das System eine Callback-Funktion aufrufen, die Sie angegeben. Diese Callback-Funktion EndInvoke() aufruft und Beendigung des asynchronen Aufrufs verarbeitet.
Die folgenden Codebeispiele zeigen diese Muster aufrufen und vergleichen Sie sie mit einem synchronen Aufruf mithilfe der folgenden Funktion:
string LongRunningMethod (int iCallTime, out int iExecThread){
Thread.Sleep (iCallTime) ;
iExecThread = AppDomain.GetCurrentThreadId ();
return "MyCallTime was " + iCallTime.ToString() ;
}


LongRunningMethod() simuliert eine Funktion, die für lange Zeit im Ruhezustand ausgeführt wird. Es gibt die Schlafzeit und die ID des Threads, der sie ausführt, zurück. Wenn Sie es asynchron aufrufen, finden Sie so, dass die Thread-ID des ausführenden Threads verschieden von der des aufrufenden Threads ist.

Der erste Schritt ist den Delegaten definieren, der die Funktion umschließt:
delegate string MethodDelegate(int iCallTime, out int iExecThread)  ;

Beispiel 1: Aufrufen einer Methode synchron

Dieses Beispiel veranschaulicht, wie LongRunningMethod() mit einem MethodDelegate -Delegaten synchron aufrufen. Die Proben dagegen durch Aufrufe asynchron.
  1. Starten Sie Microsoft Visual Studio .NET oder Microsoft Visual Studio 2005.
  2. Erstellen Sie ein neues Visual C# Konsolenanwendungsprojekt mit dem Namen AsyncDemo.
  3. Fügen Sie eine Klasse mit dem Namen AsyncDemo, die dem Projekt eine neue CS-Datei wie folgt definiert ist:
    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() ) );
    }
    }

    Diese Klasse wird später veranschaulicht, wie asynchrone Aufrufe funktionieren. Anfänglich enthält es nur die DemoSyncCall() -Methode, die veranschaulicht, wie Sie den Delegaten synchron aufrufen.
  4. Fügen Sie den folgenden Code in den Körper der Main -Funktion, die Visual Studio im Projekt automatisch erstellt:
    static void Main(string[] args){
    AsyncDemo ad = new AsyncDemo () ;
    ad.DemoSyncCall() ;
    }

  5. Drücken Sie STRG + F5, um die Anwendung auszuführen.

Beispiel 2: Aufrufen einer Methode asynchron mit dem EndInvoke() -Aufruf-Muster

In diesem Abschnitt Ruft das Beispiel die gleiche Methode asynchron. Call-Muster, das verwendet wird, ist BeginInvokeaufgerufen, einige Arbeiten am Haupthread, und rufen Sie EndInvoke(). Beachten Sie, dass EndInvoke() nicht zurück, bis der asynchrone Aufruf abgeschlossen ist. Dieser Aufruf Muster eignet sich der aufrufende Thread möchten arbeiten zur gleichen Zeit den asynchrone Aufruf ausführt. Arbeit gleichzeitig auftreten verbessern die Leistung von vielen. Allgemeine Aufgaben asynchron ausführen auf diese Weise werden Datei-oder Netzwerkvorgänge.
  1. Fügen Sie eine Methode namens DemoEndInvoke() , die AsyncDemo -Klasse. Die Funktion DemoEndInvoke veranschaulicht, wie Delegaten asynchron aufrufen.
    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. Bearbeiten Sie den Quellcode Main , damit sie den folgenden Code enthält:
    static void Main(string[] args){
    AsyncDemo ad = new AsyncDemo () ;
    ad.DemoEndInvoke() ;
    }

  3. Drücken Sie STRG + F5, um die Anwendung auszuführen.

Beispiel 3: Eine Methode asynchron aufrufen und mit WaitHandle warten Aufruf abgeschlossen


In diesem Abschnitt im Beispiel ruft die Methode asynchron und WaitHandle wartet, bevor EndInvoke()aufgerufen. Die von BeginInvoke() zurückgegebene IAsyncResult hat AsyncWaitHandle -Eigenschaft. Diese Eigenschaft gibt ein WaitHandle , das signalisiert wird, wenn der asynchrone Aufruf abgeschlossen ist. Warten auf ein WaitHandle ist eine gängige Technik der Thread-Synchronisierung. Der aufrufende Thread wartet auf das WaitHandle mithilfe der WaitOne() -Methode des WaitHandle. WaitOne() blockiert, bis das WaitHandle signalisiert wird. WaitOne() gibt zusätzliche Arbeit möglich vor dem Aufruf von EndInvoke(). Wie im vorherigen Beispiel eignet sich dieses Verfahren zum Ausführen von Datei- oder Netzwerkoperationen, die andernfalls aufrufenden Hauptthread blockiert würde.
  1. Fügen Sie eine Funktion namens DemoWaitHandle() , die AsyncDemo -Klasse. Die DemoWaitHandle() -Funktion veranschaulicht den Delegaten asynchron aufrufen.
    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. Bearbeiten Sie den Quellcode Main , damit sie den folgenden Code enthält:
    static void Main(string[] args){
    AsyncDemo ad = new AsyncDemo () ;
    ad.DemoWaitHandle () ;
    }

  3. Drücken Sie STRG + F5, um die Anwendung auszuführen.

Beispiel 4: Aufrufen einer Methode asynchron aus Musters Aufruf abrufen

In diesem Abschnitt fragt das Beispiel das IAsyncResult -Objekt, um festzustellen, wann der asynchrone Aufruf abgeschlossen ist. Das von BeginInvoke() zurückgegebene IAsyncResult -Objekt hat eine IsCompleted -Eigenschaft, die nach Abschluss des asynchronen Aufrufs True zurückgibt. Sie können EndInvoke()aufrufen. Dieser Aufruf-Muster ist nützlich, wenn Ihre Anwendung Arbeit ausführt, die nicht durch eine lang andauernde Funktionsaufruf blockiert werden soll. Eine Microsoft Windows-Anwendung ist ein Beispiel dafür. Der Hauptthread der Anwendung Windows kann weiterhin Benutzereingabe zu verarbeiten, während ein asynchroner Aufruf ausgeführt wird. Es kann in regelmäßigen Abständen überprüfen IsCompleted um festzustellen, ob der Aufruf abgeschlossen wurde. EndInvoke aufgerufen, wenn IsCompleted Truezurückgibt. Da EndInvoke() blockiert, bis der asynchrone Vorgang abgeschlossen ist, wird die Anwendung aufrufen nicht diese Wenn bekannt ist, dass der Vorgang abgeschlossen ist.
  1. Fügen Sie eine Funktion namens DemoPolling() , die AsyncDemo -Klasse. Die Funktion DemoPolling() veranschaulicht, wie Delegaten asynchron aufrufen und Abruf angezeigt, wenn der Vorgang abgeschlossen ist.
    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. Bearbeiten Sie den Quellcode für Main. Ersetzen Sie Inhalt der Funktion durch den folgenden Code:
    static void Main(string[] args){
    AsyncDemo ad = new AsyncDemo () ;
    ad.DemoPolling () ;
    }

  3. Drücken Sie STRG + F5, um die Anwendung auszuführen.

Beispiel 5: Nach Abschluss eine asynchrone Methode einen Rückruf ausführt

In diesem Abschnitt enthält das Beispiel einen Rückrufdelegaten auf die BeginInvoke() -Funktion, die bei Beendigung des asynchronen Aufrufs ausgeführt. Der Rückruf EndInvoke() aufruft und die Ergebnisse des asynchronen Aufrufs verarbeitet. Dieser Aufruf-Muster ist nützlich, wenn der Thread, der den asynchronen Aufruf gestartet nicht die Ergebnisse des Aufrufs. Das System Ruft den Rückruf auf einem anderen Thread als der initiierende Thread bei Beendigung des asynchronen Aufrufs.


Um diesen Aufruf Muster zu verwenden, müssen Sie einen Delegaten vom Typ AsyncCallback -vorletzten Parameter der Funktion BeginInvoke() übergeben. BeginInvoke() hat auch einen abschließenden Parameter von Objekttyp, in dem Sie ein Objekt übergeben können . Dieses Objekt wird für die Rückruffunktion aufgerufen wird. Ein wichtiger Verwendungszweck für diesen Parameter ist an den Delegaten übergeben, mit der der Anruf. Die Callback-Funktion können Sie die Funktion EndInvoke() Delegat Anruf. Dieses Muster Aufruf wird unten gezeigt.
  1. Fügen Sie zwei Methoden mit dem Namen DemoCallback() und MyAsyncCallback() der AsyncDemo -Klasse. Die DemoCallback() -Methode demonstriert, wie Delegaten asynchron aufrufen. Ein Delegat verwendet, um die Methode MyAsyncCallback() Umschließen des Systems beim Abschluss des asynchronen Vorgangs aufgerufen. MyAsyncCallback() ruft 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. Bearbeiten Sie den Quellcode für Main. Ersetzen Sie Inhalt der Funktion durch den folgenden Code:
    static void Main(string[] args){
    AsyncDemo ad = new AsyncDemo () ;
    ad.DemoCallback() ;
    }

  3. Drücken Sie STRG + F5, um die Anwendung auszuführen.
Eigenschaften

Artikelnummer: 315582 – Letzte Überarbeitung: 21.01.2017 – Revision: 1

Feedback