Utilizar un delegado AsyncCallback para finalizar una operación asincrónica
Actualización: noviembre 2007
Aquellas aplicaciones que pueden realizar otra tarea mientras esperan los resultados de una operación asincrónica, no se deberían bloquear mientras esperan a que la operación finalice. Utilice una de las siguientes opciones para seguir ejecutando instrucciones mientras se está a la espera de que una operación asincrónica finalice:
Utilice un delegado AsyncCallback para procesar los resultados de la operación asincrónica en un subproceso independiente. Este tema muestra la ejecución de dicho procedimiento.
Utilice la propiedad IsCompleted de la interfaz IAsyncResult devuelta por el método BeginnombreDeOperación de la operación asincrónica para determinar si la operación se ha completado. Para obtener un ejemplo de este procedimiento, vea Sondear el estado de una operación asincrónica.
Ejemplo
El siguiente ejemplo de código muestra cómo utilizar los métodos asincrónicos en la clase Dns con el fin de recuperar información sobre el Sistema de nombres de dominio (DNS) para equipos especificados por el usuario. Este ejemplo crea un delegado AsyncCallback que hace referencia al método ProcessDnsInformation. Se llama a este método una vez por cada solicitud asincrónica con el fin de obtener información DNS.
Obsérvese que el host especificado por el usuario se pasa al parámetro BeginGetHostByNameObject. Para obtener un ejemplo que muestra cómo definir y utilizar un objeto de estado más complejo, vea Utilizar un delegado AsyncCallback y un objeto State.
'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);
}
}
}
}
Vea también
Conceptos
Información general sobre el modelo asincrónico basado en eventos
Llamar a métodos asincrónicos mediante IAsyncResult
Utilizar un delegado AsyncCallback y un objeto State