다음을 통해 공유


비동기 대리자 프로그래밍 샘플

업데이트: 2007년 11월

다음 코드 예제에서는 몇 개의 숫자를 인수분해하는 클래스를 사용하여 .NET 비동기 프로그래밍의 사용 방법을 보여 줍니다. 이 예제에서는 지정된 숫자의 소수를 계산하는 단일 메서드 Factorize가 있는 클래스를 정의합니다. 또한 이 예제에서는 Factorize 메서드의 시그니처와 일치하는 시그니처가 있는 AsyncFactorCaller라는 대리자도 정의합니다. 이 대리자는 DemonstrateAsyncPattern 클래스의 메서드에서 Factorize 메서드를 비동기 방식으로 호출하는 데 사용됩니다. FactorizeNumberUsingCallback 메서드는 AsyncCallback 대리자를 사용하여 비동기 작업을 종료하고 결과를 확인하는 방법을 보여 줍니다. FactorizeNumberAndWait 메서드는 해당 비동기 작업이 완료되었는지 여부를 확인하는 정기적인 폴링을 보여 줍니다.

예제

Imports System
Imports System.Threading
Imports System.Runtime.Remoting.Messaging

Namespace Examples.AdvancedProgramming.AsynchronousOperations

    ' Create a class that factors a number.
    Public Class PrimeFactorFinder
       Public Shared Function Factorize( _
                    ByVal number as Integer, _
                    Byref primefactor1 as Integer, _
                    Byref primefactor2 as Integer) as Boolean
          primefactor1 = 1
          primefactor2 = number

          ' Factorize using a low-tech approach.
          For i as Integer =2 To number-1
             If 0 =  (number MOD i)
                primefactor1 = i
                primefactor2 = number / i
                Exit For
             End If
          Next i
          If 1 = primefactor1
             Return False
          Else
             Return True
          End If
       End Function
    End Class

    ' Create an asynchronous delegate that matches the Factorize method.
    Public delegate Function AsyncFactorCaller ( _
             number as Integer, _
             ByRef primefactor1 as Integer, _
             ByRef primefactor2 as Integer) as Boolean

    Public Class DemonstrateAsyncPattern
              ' The waiter object is used to keep the main application thread
              ' from terminating before the callback method completes.
              Dim waiter as ManualResetEvent 
        ' Define the method that is invoked when the results are available.
        Public Sub FactorizedResults(result as IAsyncResult)
              Dim factor1 as Integer =0
              Dim factor2 as Integer =0

              ' Extract the delegate from the 
              ' System.Runtime.Remoting.Messaging.AsyncResult.
              Dim ar as AsyncResult = CType (result, AsyncResult)
              Dim delegateObject as Object = ar.AsyncDelegate
              Dim factorDelegate as AsyncFactorCaller =  _
                    CType(delegateObject, AsyncFactorCaller)

              Dim number as Integer = CType(result.AsyncState, Integer)
              Dim answer as Boolean

              ' Obtain the result.
              answer = factorDelegate.EndInvoke(factor1, factor2, result)
              ' Output the results.
              Console.WriteLine("On CallBack: Factors of {0} : {1} {2} - {3}", _
                  number, factor1, factor2, answer)
             waiter.Set()
           End Sub

       ' The following method demonstrates the asynchronous pattern using a callback method.
       Public Sub FactorizeNumberUsingCallback()
          Dim  factorDelegate as AsyncFactorCaller
          Dim result as IAsyncResult
          Dim callback as AsyncCallback
          Dim number as Integer = 1000589023
          Dim temp as Integer = 0 

         ' Waiter will keep the main application thread from 
         '' ending before the callback completes because
         ' the main thread blocks until the waiter is signaled
         ' in the callback.
          waiter = new ManualResetEvent(False)
          factorDelegate = AddressOf PrimeFactorFinder.Factorize
          ' Define the AsyncCallback delegate.
          callBack = new AsyncCallback (AddressOf FactorizedResults)

          ' Asynchronously invoke the Factorize method.
          result = factorDelegate.BeginInvoke( _
                               number, _
                               temp, _
                               temp, _
                               callBack, _
                               number) 
       End Sub

       ' The following method demonstrates the asynchronous pattern 
       ' using a BeginInvoke, followed by waiting with a time-out.
       Public Sub FactorizeNumberAndWait()
           Dim factorDelegate as AsyncFactorCaller
           Dim result as IAsyncResult

           factorDelegate = AddressOf PrimeFactorFinder.Factorize

          Dim number as Integer = 1000589023
          Dim temp as Integer = 0 

          ' Asynchronously invoke the Factorize method.
          result = factorDelegate.BeginInvoke( _
                            number, _
                            temp, _ 
                            temp, _
                            Nothing, _
                            Nothing) 

          Do While result.IsCompleted = False
            ' Do any work you can do before waiting.
            result.AsyncWaitHandle.WaitOne(10000, false)
          Loop
          ' The asynchronous operation has completed.
          Dim factor1 as Integer = 0
          Dim factor2 as Integer = 0
          Dim answer as Boolean
          ' Obtain the result.
          answer = factorDelegate.EndInvoke(factor1, factor2, result)

         ' Output the results.
         Console.WriteLine("Sequential : Factors of {0} : {1} {2} - {3}", _ 
                           number, factor1, factor2, answer)
       End Sub

       Public Shared Sub Main()
          Dim  demonstrator as DemonstrateAsyncPattern
          demonstrator = new DemonstrateAsyncPattern()
          demonstrator.FactorizeNumberUsingCallback()
          demonstrator.FactorizeNumberAndWait()
       End Sub
    End Class
End Namespace
using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
    // Create a class that factors a number.
    public class PrimeFactorFinder
    {
       public static bool Factorize(
                    int number,
                    ref int primefactor1,
                    ref int primefactor2)
       {
          primefactor1 = 1;
          primefactor2 = number;

          // Factorize using a low-tech approach.
          for (int i=2;i<number;i++)
          {
             if (0 == (number % i))
             {
                primefactor1 = i;
                primefactor2 = number / i;
                break;
             }
          }
          if (1 == primefactor1 )
             return false;
          else
             return true   ;
       }
    }

    // Create an asynchronous delegate that matches the Factorize method.
    public delegate bool AsyncFactorCaller (
             int number, 
             ref int primefactor1,
             ref int primefactor2);

    public class DemonstrateAsyncPattern
    {
        // The waiter object used to keep the main application thread
        // from terminating before the callback method completes.
        ManualResetEvent waiter;

        // Define the method that receives a callback when the results are available.
        public void FactorizedResults(IAsyncResult result)
           {
              int factor1=0;
              int factor2=0; 

              // Extract the delegate from the 
              // System.Runtime.Remoting.Messaging.AsyncResult.
              AsyncFactorCaller factorDelegate = (AsyncFactorCaller)((AsyncResult)result).AsyncDelegate;
              int number = (int) result.AsyncState;
              // Obtain the result.
              bool answer = factorDelegate.EndInvoke(ref factor1, ref factor2, result);
              // Output the results.
              Console.WriteLine("On CallBack: Factors of {0} : {1} {2} - {3}", 
                  number, factor1, factor2, answer);
              waiter.Set();
           }

       // The following method demonstrates the asynchronous pattern using a callback method.
       public void FactorizeNumberUsingCallback()
       {
          AsyncFactorCaller factorDelegate = new AsyncFactorCaller (PrimeFactorFinder.Factorize);
          int number = 1000589023;
          int temp=0; 
          // Waiter will keep the main application thread from 
          // ending before the callback completes because
          // the main thread blocks until the waiter is signaled
          // in the callback.
           waiter = new ManualResetEvent(false);

          // Define the AsyncCallback delegate.
          AsyncCallback callBack = new AsyncCallback(this.FactorizedResults);

          // Asynchronously invoke the Factorize method.
          IAsyncResult result = factorDelegate.BeginInvoke(
                               number, 
                               ref temp, 
                               ref temp, 
                               callBack, 
                               number); 

          // Do some other useful work while 
          // waiting for the asynchronous operation to complete.

          // When no more work can be done, wait.
          waiter.WaitOne();
       }

       // The following method demonstrates the asynchronous pattern 
       // using a BeginInvoke, followed by waiting with a time-out.
       public void FactorizeNumberAndWait()
       {
          AsyncFactorCaller factorDelegate = new AsyncFactorCaller (PrimeFactorFinder.Factorize);

          int number = 1000589023;
          int temp=0; 

          // Asynchronously invoke the Factorize method.
          IAsyncResult result = factorDelegate.BeginInvoke(
                            number, 
                            ref temp, 
                            ref temp, 
                            null, 
                            null); 

          while (!result.IsCompleted)
          {
            // Do any work you can do before waiting.
            result.AsyncWaitHandle.WaitOne(10000, false);
          }
          // The asynchronous operation has completed.
          int factor1=0;
          int factor2=0; 

         // Obtain the result.
         bool answer = factorDelegate.EndInvoke(ref factor1, ref factor2, result);

         // Output the results.
         Console.WriteLine("Sequential : Factors of {0} : {1} {2} - {3}", 
                           number, factor1, factor2, answer);
       }

       public static void Main()
       {
          DemonstrateAsyncPattern demonstrator = new DemonstrateAsyncPattern();
          demonstrator.FactorizeNumberUsingCallback();
          demonstrator.FactorizeNumberAndWait();
       }
    }
}