■ IAsyncStateMachine 인터페이스 : 비동기 처리하기

------------------------------------------------------------------------------------------------------------------------


TestProject.zip


GetTextAsyncStateMachine.cs

 

 

using System;

using System.Runtime.CompilerServices;

using System.Threading.Tasks;

 

namespace TestProject

{

    /// <summary>

    /// 텍스트 구하기 비동기 상태 머신

    /// </summary>

    public class GetTextAsyncStateMachine : IAsyncStateMachine

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region Field

 

        /// <summary>

        /// 프로그램

        /// </summary>

        public Program Program;

 

        /// <summary>

        /// 비동기 태스크 메소드 빌더

        /// </summary>

        public AsyncTaskMethodBuilder<string> Builder;

 

        /// <summary>

        /// 상태

        /// </summary>

        public int State;

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 태스크 대기자

        /// </summary>

        private TaskAwaiter<string> taskAwaiter;

 

        /// <summary>

        /// 문자열 태스크

        /// </summary>

        private Task<string> stringTask;

 

        /// <summary>

        /// 텍스트

        /// </summary>

        private string text;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region (IAsyncStateMachine) 다음으로 이동하기 - MoveNext()

 

        /// <summary>

        /// 다음으로 이동하기

        /// </summary>

        public void MoveNext()

        {

            try

            {

                TaskAwaiter<string> taskAwaiter;

 

                switch(State)

                {

                    case 0 :

 

                        taskAwaiter = this.taskAwaiter;

 

                        this.taskAwaiter = new TaskAwaiter<string>();

 

                        State = -1;

 

                        break;

 

                    default :

 

                        this.stringTask = new TaskFactory().StartNew(() => { return "TEST"; });

 

                        taskAwaiter = this.stringTask.GetAwaiter();

 

                        if(taskAwaiter.IsCompleted == false)

                        {

                            State = 0;

 

                            this.taskAwaiter = taskAwaiter;

 

                            GetTextAsyncStateMachine asyncStateMachine = this;

 

                            Builder.AwaitUnsafeOnCompleted(ref taskAwaiter, ref asyncStateMachine);

 

                            return;

                        }

 

                        break;

                }

 

                this.text = taskAwaiter.GetResult();

            }

            catch(Exception exception)

            {

                State = -2;

 

                Builder.SetException(exception);

 

                return;

            }

 

            State = -2;

 

            Builder.SetResult(this.text);

        }

 

        #endregion

        #region (IAsyncStateMachine) 상태 머신 설정하기 - SetStateMachine(asyncStateMachine)

 

        /// <summary>

        /// 상태 머신 설정하기

        /// </summary>

        /// <param name="asyncStateMachine">비동기 상태 머신</param>

        public void SetStateMachine(IAsyncStateMachine asyncStateMachine)

        {

        }

 

        #endregion

    }

}

 

 

CallAsyncStateMachine.cs

 

 

using System;

using System.Runtime.CompilerServices;

 

namespace TestProject

{

    /// <summary>

    /// 호출하기 비동기 상태 머신

    /// </summary>

    public class CallAsyncStateMachine : IAsyncStateMachine

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region Field

 

        /// <summary>

        /// 프로그램

        /// </summary>

        public Program Program;

 

        /// <summary>

        /// 비동기 태스크 메소드 빌더

        /// </summary>

        public AsyncTaskMethodBuilder Builder;

 

        /// <summary>

        /// 상태

        /// </summary>

        public int State;

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 태스크 대기자

        /// </summary>

        private TaskAwaiter<string> taskAwaiter;

 

        /// <summary>

        /// 현재 시간

        /// </summary>

        private string currentTime;

 

        /// <summary>

        /// 텍스트

        /// </summary>

        private string text;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region (IAsyncStateMachine) 다음으로 이동하기 - MoveNext()

 

        /// <summary>

        /// 다음으로 이동하기

        /// </summary>

        public void MoveNext()

        {

            try

            {

                TaskAwaiter<string> taskAwaiter;

 

                switch(State)

                {

                    case 0 :

 

                        taskAwaiter = this.taskAwaiter;

 

                        this.taskAwaiter = new TaskAwaiter<string>();

 

                        State = -1;

 

                        break;

 

                    default:

 

                        this.currentTime = DateTime.Now.ToString();

 

                        taskAwaiter = Program.GetTextAsync().GetAwaiter();

 

                        if(taskAwaiter.IsCompleted == false)

                        {

                            State = 0;

 

                            this.taskAwaiter = taskAwaiter;

 

                            CallAsyncStateMachine callAsyncStateMachine = this;

 

                            Builder.AwaitUnsafeOnCompleted(ref taskAwaiter, ref callAsyncStateMachine);

 

                            return;

                        }

 

                        break;

                }

 

                this.text = taskAwaiter.GetResult();

 

                Console.WriteLine(this.currentTime + " : " + this.text);

            }

            catch(Exception exception)

            {

                State = -2;

 

                Builder.SetException(exception);

 

                return;

            }

 

            State = -2;

 

            Builder.SetResult();

        }

 

        #endregion

        #region (IAsyncStateMachine) 상태 머신 설정하기 - SetStateMachine(stateMachine)

 

        /// <summary>

        /// 상태 머신 설정하기

        /// </summary>

        /// <param name="asyncStateMachine">비동기 상태 머신</param>

        public void SetStateMachine(IAsyncStateMachine asyncStateMachine)

        {

        }

 

        #endregion

    }

}

 

 

Program.cs

 

 

using System;

using System.Runtime.CompilerServices;

using System.Threading.Tasks;

 

namespace TestProject

{

    /// <summary>

    /// 프로그램

    /// </summary>

    public class Program

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region 프로그램 시작하기 - Main()

 

        /// <summary>

        /// 프로그램 시작하기

        /// </summary>

        private static void Main()

        {

            Console.Title = "IAsyncStateMachine 인터페이스 : 비동기 처리하기";

 

            Program program = new Program();

 

            Task task = program.CallAsync();

 

            task.GetAwaiter().GetResult();

        }

 

        #endregion

 

        #region 비동기 텍스트 구하기 - GetStringAsync()

 

        /// <summary>

        /// 비동기 텍스트 구하기

        /// </summary>

        /// <returns>문자열 태스크</returns>

        public Task<string> GetTextAsync()

        {

            GetTextAsyncStateMachine asyncStateMachine = new GetTextAsyncStateMachine

            {

                Program = this,

                Builder = AsyncTaskMethodBuilder<string>.Create(),

                State   = -1

            };

 

            asyncStateMachine.Builder.Start(ref asyncStateMachine);

 

            return asyncStateMachine.Builder.Task;

        }

 

        #endregion

        #region 비동기 호출하기 - CallAsync()

 

        /// <summary>

        /// 비동기 호출하기

        /// </summary>

        /// <returns>태스크</returns>

        public Task CallAsync()

        {

            CallAsyncStateMachine asyncStateMachine = new CallAsyncStateMachine

            {

                Program = this,

                Builder = AsyncTaskMethodBuilder.Create(),

                State   = -1

            };

 

            asyncStateMachine.Builder.Start(ref asyncStateMachine);

 

            return asyncStateMachine.Builder.Task;

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker

댓글을 달아 주세요