NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    C# C# .NET 매크로 프로그램 만들기. (동기와 비동기 처리 방법)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 이전 시간에 만든 스크립트 실행 액션은 기본적으로 비동기로 작동합니다. 비동기란, 자신을 실행한 부모 스크립트와 동시에 실행된다는 의미입니다. 동기(Synchronous)와 비동기(Asynchronous)의 차이점은 아래 그림에서 잘 설명하고 있습니다.

    UE2LauB.png

     

     

    그래서, 엔지엠 매크로에서도 동기적인 처리와 비동기적인 처리를 사용자가 선택할 수 있도록 옵션을 추가해줘야 합니다. 이 내용은 앞서 스크립트 실행에서 언급만 하고, 구현은 하지 않았었는데요. 이번 시간에 비동기적으로 처리되던 것을 동기적으로 처리할 수 있게 옵션을 추가하고, 코드를 수정하겠습니다.

     

    아래와 같이 속성을 하나 추가하세요.

            [LocalizedCategory("Action")]
            [LocalizedDisplayName("UseAsynchronous")]
            [LocalizedDescription("UseAsynchronous")]
            [Browsable(true)]
            [DefaultValue(false)]
            public bool UseAsynchronous { get; set; }

     

    동기와 비동기 처리를 하기전에 플레이어의 상태를 알 수 있어야 합니다. 동기적으로 동작하려면, 서브 스크립트가 동작중인지 또는 스크립트가 완료 상태인지를 알아야 합니다. 그래야 자신의 상태를 변경할 수 있기 때문입니다. 지금은 상태가 변화하는 값을 속성으로 만들었지만, 추후에는 이벤트로 처리할 예정입니다. 이벤트로 처리하는 이유는 외부에서 라이브러리를 사용할 때 좀 더 구현이 쉽도록 하기 위함입니다.

     

    아래는 솔루션 전체의 범용 값을 정의하고 있는 클래스인데요. 이 클래스 안에 플레이어 상태를 정의 해두었습니다. 좀 더 디테일한 정보를 제공하기 위해서는 Playing, Played, Stopping, Stopped 등등... 상태 정보를 추가해야 합니다. 우선은, 여기까지만 구현할께요.

    class Definition
    {
      public enum PlayerState
      {
        Play = 0,
        Stop = 1,
        Pause = 2
      }
    }

     

    플레이어 인터페이스에도 속성을 추가 해줍니다.

    Ai.Definition.PlayerState State { get; }

     

    인터페이스는 읽기 전용으로 정의되어 있습니다. 실제 플레이어에서는 아래와 같이 구현합니다.

    public Ai.Definition.PlayerState State { get; private set; } = Definition.PlayerState.Stop;

     

    이와같이 읽기 전용으로 속성을 만드는 이유는 외부에서 상태를 변경하면 안되기 때문입니다. 처음 플레이어를 디자인하고, 설계할 때 실행, 중지, 일시중지는 외부에서 접근할 수 있지만, 실제 스크립트가 실행중일 때는 내부에서만 상태를 변경합니다. 만약, 매인과 수많은 서브 스크립트가 실행중일 때 외부에서 상태를 변경하게 되면 제대로 중지가 되지 않아서 메모리 릭(Leak)이 발생할 수 있는 위험이 존재합니다.

     

    플레이어의 상태를 변경하는 시점을 유의해야 합니다. 멀티 스레딩 환경에서 1000분의 1초로 동작하는 경우 시작점과 끝점을 어디로 설정할지에 따라서 스크립트가 꼬일수도 있습니다. 단순히 예를 들어서 실행 버튼을 누르고, 다른 스크립트에서 상태가 변경되었는지 체크할 때를 생각해볼께요. 대부분의 경우 문제가 없겠지만, 실행 버튼을 누르자마자 상태를 체크한다면 상태가 업데이트 되기 전이라서 멈춰있는 상태로 인식할겁니다. 이 후 스크립트가 실행될텐데요. 이벤트로 처리하지 않으면 다음 체크 시점에서야 실행 여부를 확인할 수 있게됩니다. 이 때 상태 업데이트에 대한 갭(Gap)이 발생해서 정확한 동작을 보장하기가 어렵습니다.

     

    Play, Stop, Pause 메소드마다 각각 자신의 상태를 변경하는 코드를 아래와 같이 추가해야 합니다.

    this.State = Definition.PlayerState.Play;

     

    이제 상태를 저장했으므로 동기 모드에서 매크로를 실행할 때 어떻게 처리해야 하는지 알아볼까요? 새롭게 추가한 속성의 값을 체크해서 로직을 분기했습니다. 이전에는 실행만 있었는데요. 아래와 같이 서브 플레이어의 상태에 따라서 자신을 멈추고, 재실행하는 구조입니다.

    var subPlayer = player?.Children?.Where(w => w.Id == SelectScriptFile).FirstOrDefault();
    
    if (subPlayer == null)
    {
        subPlayer = player?.AddSubPlayer(SelectScriptFile);
        if (UseAsynchronous)
            subPlayer?.Play();
        else
        {
            player?.Pause(true);
            subPlayer?.Play();
    
            while (subPlayer?.State == Definition.PlayerState.Play)
                Task.Delay(1).Wait();
    
            player?.Play();
        }
    }
    else
    {
        if (subPlayer.IsPaused)
            subPlayer.Play();
    }

     

    완성된 기능을 테스트 해볼께요. 아래와 같이 1초마다 윈도우 바탕화면을 클릭하는 스크립트를 하나 만들었습니다.

    GzAsMLp.png

     

     

    비동기를 사용하지 않기 때문에 동기 모드로 작동합니다. 서브 스크립트가 실행되고, 마지막 클릭이 실행되어야 합니다.

    DlC3dZK.png

     

     

    우선, 동기 모드로 실행 해볼께요. 아래 동영상처럼 서브 스크립트가 모두 실행되고, 마지막 자신의 클릭 액션이 실행됩니다.

     

     

    아래는 비동기 모드로 실행한 동영상입니다. 비동기 모드에서 위와 같이 실행하면 서브스크립트가 실행되지 않고, 바로 완료됩니다. 매인 스크립트가 완료되면서 자신에게 속한 자식 플레이어들도 모두 종료시키기 때문입니다. 이렇게 디자인한 이유는 이전 글에서 확인할 수 있습니다. 자세한 내용은 이전 글을 한번 읽어보세요^^

     

    동기 모드와 같이 동작시키려면 아래 동영상에서 마지막 클릭 액션의 지연을 5초로 설정해야 합니다. 서브 스크립트가 완료되기까지 4초가 걸리기 때문인데요. 이렇게 해야 서브 스크립트가 완료된 후 매인 스크립트가 완료됩니다. 비동기로 동작한다는걸 알 수 있는 부분은 마지막 클릭 액션에 5초를 설정했지만, 서브 스크립트와 연속된 동작처럼 1초 간격으로 윈도우 바탕화면의 아이콘을 클릭한다는걸로 판단할 수 있습니다.

     

     

    동기와 비동기의 예를 좀 더 자세하게 살펴보려면 이미지 매치나 이미지 서치 또는 별도의 비즈니스 로직을 가지는 스크립트를 만들어야 합니다. 가령 웹페이지에서 특정 사이트에 회원가입하면서 게임을 한다거나, 엑셀에 데이터를 입력하면서 웹페이지에 업로드가 되는지 체크하는등등... 동시다발적으로 이루어지는 작업에서 비동기 모드를 사용하면 컴퓨팅 파워가 올라갑니다. 컴퓨터의 가용 리소스를 최대한으로 사용하려면 비동기로 매크로를 실행하는게 좋습니다.

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.