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

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


TestProject.zip


AsyncStateMachine.cs

 

 

using System;

using System.Runtime.CompilerServices;

 

namespace TestProject

{

    /// <summary>

    /// 비동기 상태 머신

    /// </summary>

    public class AsyncStateMachine : 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;

 

                            AsyncStateMachine asyncStateMachine = this;

 

                            this.Builder.AwaitUnsafeOnCompleted(ref taskAwaiter, ref asyncStateMachine);

 

                            return;

                        }

 

                        break;

                }

 

                this.text = taskAwaiter.GetResult();

 

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

            }

            catch(Exception e)

            {

                State = -2;

 

                Builder.SetException(e);

 

                return;

            }

 

            State = -2;

 

            Builder.SetResult();

        }

 

        #endregion

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

 

        /// <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 비동기 텍스트 구하기 - GetTextAsync()

 

        /// <summary>

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

        /// </summary>

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

        public async Task<string> GetTextAsync()

        {

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

        }

 

        #endregion

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

 

        /// <summary>

        /// 비동기 호출하기

        /// </summary>

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

        public Task CallAsync()

        {

            AsyncStateMachine asyncStateMachine = new AsyncStateMachine

            {

                Program = this,

                Builder = AsyncTaskMethodBuilder.Create(),

                State   = -1

            };

 

            asyncStateMachine.Builder.Start(ref asyncStateMachine);

 

            return asyncStateMachine.Builder.Task;

        }

 

        #endregion

    }

}

 

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

Posted by 사용자 icodebroker