Amazon Web Services .NET 용 비동기 API

 

.NET Framework 4.5, Windows Store 및 Windows Phone 8 용 비동기 API

 

.NET 용 AWS SDK는 .NET Framework 버전 4.5, Windows Store 및 Windows Phone 8에 대한 새로운 작업 기반 비동기 패턴을 사용한다. async 및 await 키워드를 사용하면 차단하지 않고 모든 AWS 제품에 대한 비동기 작업을 수행하고 관리 할 수 있다. 작업 기반 비동기 패턴에 대한 자세한 내용은 MSDN의 작업 기반 비동기 패턴 (TAP)을 참조하면 된다.

 

 

.NET Framework 3.5 용 비동기 API


.NET 용 AWS SDK는 .NET 클라이언트 클래스에 의해 노출 된 대부분의 메소드 호출의 비동기(async)버전을 지원한다. 비동기 메소드를 사용하면 서비스의 응답에 코드 블록이 없어도 AWS 서비스를 호출 할 수 있다. 예를 들어 Amazon S3 또는 DynamoDB에 데이터를 쓰도록 요청한 다음 AWS가 요청을 처리하는 동안 코드가 다른 작업을 계속하도록 할 수 있다.

 

비동기 요청 메서드의 구문


AWS 서비스에 비동기 요청을 하는 데에는 두 가지 단계가 있다. 첫 번째는 요청에 대한 Begin 메서드를 호출하는 것이다. 이 메서드는 비동기 작업을 시작한다. 해당 End 메서드는 서비스에서 응답을 검색하고 작업 중에 발생할 수 있는 예외를 처리 할 수 있는 기회를 제공한다.

참고

End 메서드를 호출 할 필요는 없다. 오류가 없다고 가정하면 End를 호출했는지 여부에 관계없이 비동기 작업이 완료된다.

 

Begin 메서드 구문

 

PutItemRequest와 같은 리퀘스트 오브젝트 매개변수를 가져 오는 것 외에도 비동기 Begin 메서드는 두 가지 추가 매개변수인 콜백 함수와 상태 오브젝트를 사용한다. Begin 메서드는 서비스 리퀘스트 오브젝트를 반환하는 대신 IAsyncResult 형식의 결과를 반환합니다. 이 유형의 정의에 대해서는 MSDN 설명서를 참조하면 확인할 수 있다.

 

동기식 메서드

PutItemResponse PutItem( PutItemRequest putItemRequest )

 

비동기식 메서드

IAsyncResult BeginPutItem( GetSessionTokenRequest getSessionTokenRequest, {AsyncCallback callback}, {Object state} )

 

AsyncCallback 콜백

비동기 작업이 완료되면 콜백 함수가 호출된다. 함수가 호출되면 IAsyncResult 유형의 단일 매개 변수를 받는다. 콜백 함수는 다음의 시그니처를 가진다.

void Callback( IAsyncResult asyncResult )

 

오브젝트 상태(Object state)

세 번째 매개변수인 state는 asyncResult 매개변수의 AsyncState 속성, 즉 asyncResult.AsyncState로 콜백 함수에서 사용할 수있는 사용자 정의 오브젝트이다.

 

패턴 호출(Calling Patterns)

  • 콜백 함수와 상태 객체 전달.
  • 콜백 함수를 전달하지만 상태 객체에 null을 전달한다.
  • 콜백 함수와 상태 객체 모두에 대해 null을 전달한다.

이 주제는 이러한 각 패턴의 예를 제공한다.

 

IAsyncResult.AsyncWaitHandle 사용


경우에 따라 Begin 메서드를 호출하는 코드가 비동기 작업이 완료될 때까지 대기하도록 호출하는 다른 메서드를 사용해야 할 수도 있다. 이러한 상황에서는 WaitHandle이 IAsyncResult 반환 값의 IAsyncResult.AsyncWaitHandle 속성에서 반환한 메서드를 전달할 수 있다. 그런 다음 이 메서드는 이 WaitHandle에서 WaitOne을 호출하여 비동기 작업이 완료될 때까지 대기할 수 있다.

 

예제

뒤의 모든 예제는 모두 다음 초기화 코드를 통해서 초기화 되었다고 가정한다.

public static void TestPutObjectAsync()
{
  // Create a client AmazonS3Client

  // AmazonS3Client 클라이언트를 생성한다.
  client = new AmazonS3Client();

  PutObjectResponse response;
  IAsyncResult asyncResult;

  //
  // Create a PutObject request

  // PutObject 요청을 생성한다.
  //
  // You will need to use your own bucket name below in order
  // to run this sample code.

  // 이 샘플 코드를 실행하려면 아래에 자신의 버킷 이름을 사용해야 한다.
  //
  PutObjectRequest request = new PutObjectRequest
  {
    BucketName = "{PUT YOUR OWN EXISTING BUCKET NAME HERE : 당신이 가진 실제 버킷 이름을 여기에 넣어라}",
    Key = "Item",
    ContentBody = "This is sample content..."
  };

  //
  // additional example code

  // 추가 예제 코드
  //
}

 

지정된 콜백이 없는 경우(No Callback Specified)

 

다음 예제 코드에서는 BeginPutObject를 호출하고 작업을 수행한 다음 EndPutObject를 호출하여 서비스 응답을 검색한다. EndPutObject에 대한 호출은 try 블록에 포함되어 작업 중에 발생할 수 있는 예외를 잡는다.

 

asyncResult = client.BeginPutObject(request, null, null);


while ( ! asyncResult.IsCompleted )

{
  //
  // Do some work here

  // 작업을 여기서 처리한다.
  //
}


try

{
  response = client.EndPutObject(asyncResult);
}
catch (AmazonS3Exception s3Exception)

{
  //
  // Code to process exception

  // 예외 처리 코드
  //
}

 

 

간단한 콜백(Simple Callback)

 

이 예제에서는 다음 콜백 함수가 정의되어 있다고 가정한다.

 

public static void SimpleCallback(IAsyncResult asyncResult)
{
  Console.WriteLine("Finished PutObject operation with simple callback :
간단한 콜백으로 PutObject 작업 완료");
}

 

다음 코드는 BeginPutObject를 호출하고 위의 콜백 함수를 지정한다. PutObject 작업이 완료되면 콜백 함수가 호출된다. 단순 콜백 함수는 asyncResult 매개 변수의 AsyncState 속성에 액세스하지 않기 때문에 BeginPutObject를 호출하면 state 매개 변수에 null이 지정된다. 호출 코드나 콜백 함수는 EndPutObject를 호출하지 않는다. 따라서 서비스 응답이 효과적으로 삭제되고 작업 중에 발생하는 예외는 무시된다.

 

asyncResult = client.BeginPutObject(request, SimpleCallback, null);

 


클라이언트와의 콜백(Callback with Client)

 

이 예제에서는 다음 콜백 함수가 정의되어 있다고 가정한다.

 

public static void CallbackWithClient(IAsyncResult asyncResult)
{
  try

  {
    AmazonS3Client s3Client = (AmazonS3Client) asyncResult.AsyncState;
    PutObjectResponse response = s3Client.EndPutObject(asyncResult);
    Console.WriteLine("Finished PutObject operation with client callback :
클라이언트 콜백으로 PutObject 작업 완료");
  }
  catch (AmazonS3Exception s3Exception)

  {
    //
    // Code to process exception

    // 예외 처리 코드
    //
  }
}

 

다음 코드는 BeginPutObject를 호출하고 앞의 콜백 함수를 지정한다. PutObject 작업이 완료되면 콜백 함수가 호출된다. 이 예제에서 BeginPutObject를 호출하면 state 매개 변수에 대한 AmazonS3 클라이언트 객체가 지정된다. 콜백 함수는 클라이언트를 사용하여 EndPutObject 메소드를 호출하고 서버 응답을 검색한다. 콜백이 EndPutObject를 호출할 때 연산 중에 발생한 모든 예외가 수신되므로이 호출은 try 블록 내에 배치된다.

 

asyncResult = client.BeginPutObject(request, CallbackWithClient, client);

 

 

상태 오브젝트를 사용한 콜백(Callback with State Object)

 

이 예제에서는 다음 클래스와 콜백 함수가 정의되어 있다고 가정한다.

 

class ClientState
{
  AmazonS3Client client;
  DateTime startTime;

  public AmazonS3Client Client
  {
    get { return client; }
    set { client = value; }
  }

  public DateTime Start
  {
    get { return startTime; }
    set { startTime = value; }
  }
}

 

public static void CallbackWithState(IAsyncResult asyncResult)
{
  try

  {
    ClientState state = asyncResult.AsyncState as ClientState;
    AmazonS3Client s3Client = (AmazonS3Client)state.Client;
    PutObjectResponse response = state.Client.EndPutObject(asyncResult);
    Console.WriteLine("Finished PutObject. Elapsed time(
완료된 PutObject. 경과 시간) : {0}", (DateTime.Now - state.Start).ToString());
  }
  catch (AmazonS3Exception s3Exception)

  {
    //
    // Code to process exception

    // 예외 처리 코드
    //
  }
}

 

다음 코드는 BeginPutObject를 호출하고 위의 콜백 함수를 지정한다. PutObject 작업이 완료되면 콜백 함수가 호출된다. 이 예제에서 BeginPutObject에 대한 호출은 state 매개변수에 대해 이전에 정의된 ClientState 클래스의 인스턴스를 지정한다. 이 클래스는 AmazonS3 클라이언트와 BeginPutObject가 호출된 시간을 포함한다. 콜백 함수는 AmazonS3 클라이언트 객체를 사용하고 EndPutObject 메소드를 호출하여 서버 응답을 검색한다. 콜백은 작업의 시작 시간을 추출하여 비동기 작업이 완료되는 데 걸리는 시간을 출력하는 데 사용한다.

 

이전 예제와 마찬가지로 EndPutObject가 호출될 때 작업 중에 발생하는 예외가 수신되므로 이 호출은 try 블록 내에 배치된다.

 

asyncResult = client.BeginPutObject( request, CallbackWithState, new ClientState { Client = client, Start = DateTime.Now } );

 

 

완성된 샘플

 

다음 코드 샘플은 비동기 요청 메서드를 호출 할 때 사용할 수있는 패턴을 보여준다.

 

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;

using Amazon;
using Amazon.Runtime;
using Amazon.S3;
using Amazon.S3.Model;

namespace async_aws_net
{
   class ClientState
   {
      AmazonS3Client client;
      DateTime startTime;

      public AmazonS3Client Client
      {
         get { return client; }
         set { client = value; }
      }

      public DateTime Start
      {
         get { return startTime; }
         set { startTime = value; }
      }
   }

   class Program
   {
      public static void Main(string[] args)
      {
         TestPutObjectAsync();
      }

      public static void SimpleCallback(IAsyncResult asyncResult)
      {
         Console.WriteLine("Finished PutObject operation with simple callback");
         Console.Write("\n\n");
      }

      public static void CallbackWithClient(IAsyncResult asyncResult)
      {
         try

         {
            AmazonS3Client s3Client = (AmazonS3Client) asyncResult.AsyncState;
            PutObjectResponse response = s3Client.EndPutObject(asyncResult);
            Console.WriteLine("Finished PutObject operation with client callback");
            Console.WriteLine("Service Response:");
            Console.WriteLine("-----------------");
            Console.WriteLine(response);
            Console.Write("\n\n");
         }
         catch (AmazonS3Exception s3Exception)

         {
            //
            // Code to process exception
            //
         }
      }

      public static void CallbackWithState(IAsyncResult asyncResult)
      {
         try

         {
            ClientState state = asyncResult.AsyncState as ClientState;
            AmazonS3Client s3Client = (AmazonS3Client)state.Client;
            PutObjectResponse response = state.Client.EndPutObject(asyncResult);
            Console.WriteLine("Finished PutObject operation with state callback that started at {0}",

                (DateTime.Now - state.Start).ToString() + state.Start);
            Console.WriteLine("Service Response:");
            Console.WriteLine("-----------------");
            Console.WriteLine(response);
            Console.Write("\n\n");
         }
         catch (AmazonS3Exception s3Exception)

         {
            //
            // Code to process exception
            //
         }
      }

      public static void TestPutObjectAsync()
      {
         // Create a client
         AmazonS3Client client = new AmazonS3Client();

         PutObjectResponse response;
         IAsyncResult asyncResult;

         //
         // Create a PutObject request
         //
         // You will need to change the BucketName below in order to run this
         // sample code.
         //
         PutObjectRequest request = new PutObjectRequest
         {
           BucketName = "PUT-YOUR-OWN-EXISTING-BUCKET-NAME-HERE",
           Key = "Item",
           ContentBody = "This is sample content..."
         };

         response = client.PutObject(request);
         Console.WriteLine("Finished PutObject operation for {0}.", request.Key);
         Console.WriteLine("Service Response:");
         Console.WriteLine("-----------------");
         Console.WriteLine("{0}", response);
         Console.Write("\n\n");

         request.Key = "Item1";
         asyncResult = client.BeginPutObject(request, null, null);
         while ( ! asyncResult.IsCompleted )

         {
           //
           // Do some work here
           //
         }
         try

         {
           response = client.EndPutObject(asyncResult);
         }
         catch (AmazonS3Exception s3Exception)

         {
           //
           // Code to process exception
           //
         }

         Console.WriteLine("Finished Async PutObject operation for {0}.", request.Key );
         Console.WriteLine("Service Response:");
         Console.WriteLine("-----------------");
         Console.WriteLine(response);
         Console.Write("\n\n");

         request.Key = "Item2";
         asyncResult = client.BeginPutObject(request, SimpleCallback, null);

         request.Key = "Item3";
         asyncResult = client.BeginPutObject(request, CallbackWithClient, client);

         request.Key = "Item4";
         asyncResult = client.BeginPutObject(request, CallbackWithState,
            new ClientState { Client = client, Start = DateTime.Now } );

         Thread.Sleep( TimeSpan.FromSeconds(5) );
      }
   }
}

 

 

참고사항

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

+ Recent posts