返回介绍

使用 AsyncCallback 委托和状态对象

发布于 2025-02-23 23:15:47 字数 9771 浏览 0 评论 0 收藏 0

当你使用 AsyncCallback 委托的一个单独的线程中的异步操作对结果进行处理,则可以使用的状态对象,两个回调之间传递信息以及如何检索最终结果。 本主题通过扩展中的示例演示这种做法 使用 AsyncCallback 委托结束异步操作 。

示例

下面的代码示例演示如何使用中的异步方法 Dns 类检索指定用户的计算机的域名系统 (DNS) 信息。 此示例定义并使用 HostRequest 类来存储状态信息。 A HostRequest 获取用户输入的每个计算机名创建对象。 此对象传递给 BeginGetHostByName 方法。 ProcessDnsInformation 每次请求完成后调用方法。 HostRequest 对象使用检索 AsyncState 属性。 ProcessDnsInformation 方法使用 HostRequest 要存储对象 IPHostEntry 该请求返回的或 SocketException 引发的请求。 应用程序完成后的所有请求,循环访问 HostRequest 对象,并显示的 DNS 信息或 SocketException 错误消息。

/*
The following example demonstrates using asynchronous methods to
get Domain Name System information for the specified host computer.
*/

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

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
// Create a state object that holds each requested host name, 
// an associated IPHostEntry object or a SocketException.
  public class HostRequest
  {
    // Stores the requested host name.
    private string hostName;
    // Stores any SocketException returned by the Dns EndGetHostByName method.
    private SocketException e;
    // Stores an IPHostEntry returned by the Dns EndGetHostByName method.
    private IPHostEntry entry;

    public HostRequest(string name)
    {
      hostName = name;
    }
    
    public string HostName
    {
      get 
      {
        return hostName;
      }
    }
    
    public SocketException ExceptionObject
    {
      get 
      {
        return e;
      }
      set 
      {
         e = value;
      }
    }

    public IPHostEntry HostEntry
    {
      get 
      {
        return entry;
      }
      set 
      {
        entry = value;
      }
    }
  }
  
  public class UseDelegateAndStateForAsyncCallback
  {
    // The number of pending requests.
    static int requestCounter;
    static ArrayList hostData = new ArrayList();
    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);
          // Create and store the state object for this request.
          HostRequest request = new HostRequest(host);
          hostData.Add(request);
          // Start the asynchronous request for DNS information.
          Dns.BeginGetHostEntry(host, callBack, request);
         }
      } 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.
      foreach(HostRequest r in hostData)
      {
          if (r.ExceptionObject != null)
          {
            Console.WriteLine("Request for host {0} returned the following error: {1}.", 
              r.HostName, r.ExceptionObject.Message);
          }
          else
          {
            // Get the results.
            IPHostEntry h = r.HostEntry;
            string[] aliases = h.Aliases;
            IPAddress[] addresses = h.AddressList;
            if (aliases.Length > 0)
            {
              Console.WriteLine("Aliases for {0}", r.HostName);
              for (int j = 0; j < aliases.Length; j++)
              {
                Console.WriteLine("{0}", aliases[j]);
              }
            }
            if (addresses.Length > 0)
            {
              Console.WriteLine("Addresses for {0}", r.HostName);
              for (int k = 0; k < addresses.Length; k++)
              {
                Console.WriteLine("{0}",addresses[k].ToString());
              }
            }
          }
      }
     }

    // The following method is invoked when each asynchronous operation completes.
    static void ProcessDnsInformation(IAsyncResult result)
    {
       // Get the state object associated with this request.
       HostRequest request = (HostRequest) result.AsyncState;
      try 
      {
        // Get the results and store them in the state object.
        IPHostEntry host = Dns.EndGetHostEntry(result);
        request.HostEntry = host;
      }
      catch (SocketException e)
      {
        // Store any SocketExceptions.
        request.ExceptionObject = e;
      }
      finally 
      {
        // Decrement the request counter in a thread-safe manner.
        Interlocked.Decrement(ref requestCounter);
      }
    }
  }
}
' The following example demonstrates using asynchronous methods to
' get Domain Name System information for the specified host computer.

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

Namespace Examples.AdvancedProgramming.AsynchronousOperations
' Create a state object that holds each requested host name, 
' an associated IPHostEntry object or a SocketException.
  Public Class HostRequest
    ' Stores the requested host name.
    Dim hostNameValue as string
    ' Stores any SocketException returned by the Dns EndGetHostByName method.
    Dim e as SocketException
    ' Stores an IPHostEntry returned by the Dns EndGetHostByName method.
    Dim entry as IPHostEntry

    Public Sub New(name as String)
      hostNameValue = name
    End Sub
    
    ReadOnly Public Property HostName as String
      Get
        return hostNameValue
      End Get
    End Property
    
    Public Property ExceptionObject as SocketException
      Get
        return e
      End Get
      Set
         e = value
      End Set
    End Property

    Public Property HostEntry as IPHostEntry
      Get
        return entry
      End Get
      Set
        entry = value
      End Set
    End Property
  End Class
  
  Public Class UseDelegateAndStateForAsyncCallback
    ' The number of pending requests.
    Dim Shared requestCounter as Integer
    Dim Shared hostData as ArrayList = new ArrayList()
    
    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 = AddressOf ProcessDnsInformation
      Dim host as string
      
      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)
          ' Create and store the state object for this request.
          Dim  request as HostRequest = new HostRequest(host)
          hostData.Add(request)
          ' Start the asynchronous request for DNS information.
          Dns.BeginGetHostEntry(host, callBack, request)
         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 Each r as HostRequest In hostData
          If IsNothing(r.ExceptionObject) = False
            Console.WriteLine( _ 
              "Request for host {0} returned the following error: {1}.", _
              r.HostName, r.ExceptionObject.Message)
          Else
            ' Get the results.
            Dim h as IPHostEntry = r.HostEntry
            Dim aliases() as String = h.Aliases
            Dim addresses() as IPAddress = h.AddressList
            Dim j, k as Integer
            
            If aliases.Length > 0
              Console.WriteLine("Aliases for {0}", r.HostName)
              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}", r.HostName)
              For k = 0 To addresses.Length -1
                Console.WriteLine("{0}",addresses(k).ToString())
              Next k
            End If
          End If
      Next r
     End Sub

    ' The following method is invoked when each asynchronous operation completes.
    Shared Sub ProcessDnsInformation(result as IAsyncResult)
       ' Get the state object associated with this request.
       Dim request as HostRequest= CType(result.AsyncState,HostRequest)
      Try 
        ' Get the results and store them in the state object.
        Dim host as IPHostEntry = Dns.EndGetHostEntry(result)
        request.HostEntry = host
      Catch e as SocketException
        ' Store any SocketExceptions.
        request.ExceptionObject = e
      Finally 
        ' Decrement the request counter in a thread-safe manner.
        Interlocked.Decrement(requestCounter)
      End Try
    End Sub
  End Class
End Namespace

另请参阅

基于事件的异步模式 (EAP)
基于事件的异步模式概述
使用 AsyncCallback 委托停止异步操作

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文