Verwenden eines AsyncCallback-Delegaten zum Beenden einer asynchronen Operation

Aktualisiert: November 2007

Anwendungen, die während des Wartens auf die Ergebnisse asynchroner Operationen noch weitere Aufgaben ausführen können, dürfen nicht bis zum Abschluss der Operation blockieren. Damit die Ausführung von Aufgaben während des Wartens auf den Abschluss einer asynchronen Methode fortgesetzt wird, verwenden Sie eine der folgenden Optionen:

  • Verwenden Sie einen AsyncCallback-Delegaten, um die Ergebnisse der asynchronen Operation in einem separaten Thread zu verarbeiten. Diese Vorgehensweise wird in diesem Thema veranschaulicht.

  • Verwenden Sie die IsCompleted-Eigenschaft des IAsyncResult, das von der BeginOperationName-Methode der asynchronen Operation zurückgegeben wird, um den Abschluss der Operation festzustellen. Ein Beispiel zu dieser Vorgehensweise finden Sie unter Abrufen des Status einer asynchronen Operation.

Beispiel

Das folgende Codebeispiel veranschaulicht, wie asynchrone Methoden in der Dns-Klasse verwendet werden, um DNS-Daten für Computer abzurufen, die vom Benutzer festgelegt wurden. In diesem Beispiel wird ein AsyncCallback-Delegat erzeugt, der auf die ProcessDnsInformation-Methode verweist. Diese Methode wird für jede asynchrone Anforderung von DNS-Informationen einmal aufgerufen.

Beachten Sie, dass der vom Benutzer angegebene Host an den BeginGetHostByNameObject-Parameter übergeben wird. Ein Beispiel, in dem das Definieren und Verwenden eines komplexeren Zustandsobjekts veranschaulicht wird, finden Sie unter Verwenden von AsyncCallback-Delegat und Zustandsobjekt.

'The following example demonstrates using asynchronous methods to
'get Domain Name System information for the specified host computers.
'This example uses a delegate to obtain the results of each asynchronous 
'operation.

Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Collections.Specialized
Imports System.Collections

Namespace Examples.AdvancedProgramming.AsynchronousOperations

    Public Class UseDelegateForAsyncCallback

        Dim Shared requestCounter as Integer
        Dim Shared hostData as ArrayList = new ArrayList()
        Dim Shared hostNames as StringCollection = new StringCollection()
        Shared Sub UpdateUserInterface()

            ' Print a message to indicate that the application
            ' is still working on the remaining requests.
            Console.WriteLine("{0} requests remaining.", requestCounter)
        End Sub
        Public Shared Sub Main()
            ' Create the delegate that will process the results of the 
            ' asynchronous request.
            Dim callBack as AsyncCallback
            Dim host as string
            Dim i, j, k as Integer
            callback = AddressOf ProcessDnsInformation
            Do
                Console.Write(" Enter the name of a host computer or <enter> to finish: ")
                host = Console.ReadLine()
                If host.Length > 0
                    ' Increment the request counter in a thread safe manner.
                    Interlocked.Increment(requestCounter)
                    ' Start the asynchronous request for DNS information.
                    Dns.BeginGetHostEntry(host, callBack, host)
                End If
            Loop While (host.Length > 0)

            ' The user has entered all of the host names for lookup.
            ' Now wait until the threads complete.
            Do While requestCounter > 0

                UpdateUserInterface()
            Loop

            ' Display the results.
            For i = 0 To hostNames.Count -1
                Dim dataObject as Object = hostData (i)
                Dim message as String 

                ' Was a SocketException was thrown?
                If TypeOf dataObject is String
                    message = CType(dataObject, String)
                    Console.WriteLine("Request for {0} returned message: {1}", _ 
                        hostNames(i), message)
                Else
                    ' Get the results.
                    Dim h as IPHostEntry = CType(dataObject, IPHostEntry) 
                    Dim aliases() as String = h.Aliases
                    Dim addresses() as IPAddress = h.AddressList
                    If aliases.Length > 0
                        Console.WriteLine("Aliases for 0}", hostNames(i))
                        For j = 0 To aliases.Length -1
                            Console.WriteLine("{0}", aliases(j))
                        Next j
                    End If
                    If addresses.Length > 0
                        Console.WriteLine("Addresses for {0}", hostNames(i))
                        For k = 0 To addresses.Length -1
                            Console.WriteLine("{0}",addresses(k).ToString())
                        Next k
                    End If
                End If
            Next i
       End Sub

        ' The following method is called when each asynchronous operation completes.
        Shared Sub ProcessDnsInformation(result as IAsyncResult)

            Dim hostName as String = CType(result.AsyncState, String)
            hostNames.Add(hostName)
            Try 
                ' Get the results.
                Dim host as IPHostEntry = Dns.EndGetHostEntry(result)
                hostData.Add(host)
            ' Store the exception message.
            Catch e as SocketException
                hostData.Add(e.Message)
            Finally 
                ' Decrement the request counter in a thread-safe manner.
                Interlocked.Decrement(requestCounter)
            End Try
        End Sub
    End Class
End Namespace
/*
The following example demonstrates using asynchronous methods to
get Domain Name System information for the specified host computers.
This example uses a delegate to obtain the results of each asynchronous 
operation.
*/

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections.Specialized;
using System.Collections;

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
    public class UseDelegateForAsyncCallback
    {
        static int requestCounter;
        static ArrayList hostData = new ArrayList();
        static StringCollection hostNames = new StringCollection();
        static void UpdateUserInterface()
        {
            // Print a message to indicate that the application
            // is still working on the remaining requests.
            Console.WriteLine("{0} requests remaining.", requestCounter);
        }
        public static void Main()
        {
            // Create the delegate that will process the results of the 
            // asynchronous request.
            AsyncCallback callBack = new AsyncCallback(ProcessDnsInformation);
            string host;
            do
            {
                Console.Write(" Enter the name of a host computer or <enter> to finish: ");
                host = Console.ReadLine();
                if (host.Length > 0)
                {
                    // Increment the request counter in a thread safe manner.
                    Interlocked.Increment(ref requestCounter);
                    // Start the asynchronous request for DNS information.
                    Dns.BeginGetHostEntry(host, callBack, host);
                 }
            } while (host.Length > 0);
            // The user has entered all of the host names for lookup.
            // Now wait until the threads complete.
            while (requestCounter > 0)
            {
                UpdateUserInterface();
            }
            // Display the results.
            for (int i = 0; i< hostNames.Count; i++)
            {
                object data = hostData [i];
                string message = data as string;
                // A SocketException was thrown.
                if (message != null)
                {
                    Console.WriteLine("Request for {0} returned message: {1}", 
                        hostNames[i], message);
                    continue;
                }
                // Get the results.
                IPHostEntry h = (IPHostEntry) data;
                string[] aliases = h.Aliases;
                IPAddress[] addresses = h.AddressList;
                if (aliases.Length > 0)
                {
                    Console.WriteLine("Aliases for {0}", hostNames[i]);
                    for (int j = 0; j < aliases.Length; j++)
                    {
                        Console.WriteLine("{0}", aliases[j]);
                    }
                }
                if (addresses.Length > 0)
                {
                    Console.WriteLine("Addresses for {0}", hostNames[i]);
                    for (int k = 0; k < addresses.Length; k++)
                    {
                        Console.WriteLine("{0}",addresses[k].ToString());
                    }
                }
            }
       }

        // The following method is called when each asynchronous operation completes.
        static void ProcessDnsInformation(IAsyncResult result)
        {
            string hostName = (string) result.AsyncState;
            hostNames.Add(hostName);
            try 
            {
                // Get the results.
                IPHostEntry host = Dns.EndGetHostEntry(result);
                hostData.Add(host);
            }
            // Store the exception message.
            catch (SocketException e)
            {
                hostData.Add(e.Message);
            }
            finally 
            {
                // Decrement the request counter in a thread-safe manner.
                Interlocked.Decrement(ref requestCounter);
            }
        }
    }
}

Siehe auch

Konzepte

Übersicht über ereignisbasierte asynchrone Muster

Aufrufen von asynchronen Methoden unter Verwendung von IAsyncResult

Verwenden von AsyncCallback-Delegat und Zustandsobjekt

Weitere Ressourcen

Entwurfsmuster für die asynchrone Programmierung