비동기 작업의 결과를 기다리는 동안 다른 작업을 수행할 수 있는 애플리케이션은 작업이 완료될 때까지 대기를 차단해서는 안 됩니다. 비동기 작업이 완료되길 기다리는 동안 다음 옵션 중 하나를 사용하여 명령을 계속 실행합니다.
대리자를 AsyncCallback 사용하여 별도의 스레드에서 비동기 작업의 결과를 처리합니다. 이 방법은 이 항목에서 설명합니다.
IsCompleted 비동기 작업의 IAsyncResultOperationName 메서드에서 반환된 속성을 사용하여 작업이 완료되었는지 여부를 확인합니다. 이 방법을 보여 주는 예제는 비동기 작업의 상태에 대한 폴링을 참조하세요.
예시
다음 코드 예제에서는 Dns 클래스에서 비동기 메서드를 사용하여 사용자 지정 컴퓨터에 대한 DNS(Domain Name System) 정보를 검색하는 방법을 보여 줍니다. 이 예제에서는 AsyncCallback 대리자가 ProcessDnsInformation
메서드를 참조하도록 만듭니다. 이 메서드는 DNS 정보에 대한 각 비동기 요청에 대해 한 번 호출됩니다.
사용자 지정 호스트가 매개 변수에 BeginGetHostByNameObject 전달됩니다. 더 복잡한 상태 개체를 정의하고 사용하는 방법을 보여 주는 예제는 AsyncCallback 대리자 및 상태 개체 사용을 참조하세요.
/*
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($"{requestCounter} requests remaining.");
}
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 {hostNames[i]} returned message: {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 {hostNames[i]}");
for (int j = 0; j < aliases.Length; j++)
{
Console.WriteLine($"{aliases[j]}");
}
}
if (addresses.Length > 0)
{
Console.WriteLine($"Addresses for {hostNames[i]}");
for (int k = 0; k < addresses.Length; k++)
{
Console.WriteLine($"{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);
}
}
}
}
'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.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
참고하십시오
- EAP(이벤트 기반 비동기 패턴)
- 이벤트 기반 비동기 패턴 개요
- IAsyncResult를 사용하여 비동기 메서드 호출
- AsyncCallback 대리자와 상태 개체의 사용
.NET