AsyncCallback 대리자 및 상태 개체 사용
AsyncCallback 대리자를 사용하여 별도의 스레드에서 비동기 작업의 결과를 처리할 때 상태 개체를 사용하여 콜백 간에 정보를 전달하고 최종 결과를 검색할 수 있습니다. 이 항목에서는 AsyncCallback 대리자를 사용하여 비동기 작업 종료의 예를 확장하여 연습하는 방법을 보여줍니다.
예시
다음 코드 예제는 Dns 클래스에서 비동기 메서드를 사용하여 사용자가 지정한 컴퓨터의 DNS(Domain Name System) 정보를 검색하는 방법을 보여줍니다. 이 예제는 상태 정보를 저장하는 HostRequest
클래스를 정의하고 사용합니다. 사용자가 입력한 각 컴퓨터 이름에 대해 HostRequest
개체가 생성됩니다. 이 개체는 BeginGetHostByName 메서드에 전달됩니다. 요청이 완료될 때마다 ProcessDnsInformation
메서드가 호출됩니다. HostRequest
개체는 AsyncState 속성을 사용하여 검색됩니다. ProcessDnsInformation
메서드는 HostRequest
개체를 사용하여 요청에서 반환한 IPHostEntry 또는 요청에서 throw한 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.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
참고 항목
GitHub에서 Microsoft와 공동 작업
이 콘텐츠의 원본은 GitHub에서 찾을 수 있으며, 여기서 문제와 끌어오기 요청을 만들고 검토할 수도 있습니다. 자세한 내용은 참여자 가이드를 참조하세요.
.NET