■ 커스텀 태스크 사용하기

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


TestProject.zip


TestTask.cs

 

 

using System;

using System.Collections.Generic;

using System.Threading;

 

namespace TestProject

{

    /// <summary>

    /// 테스트 태스크

    /// </summary>

    public class TestTask

    {

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

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

 

        #region Field

 

        /// <summary>

        /// 스레드

        /// </summary>

        private Thread thread;

 

        /// <summary>

        /// 완료 여부

        /// </summary>

        private bool isCompleted;

 

        /// <summary>

        /// 연속 액션 리스트

        /// </summary>

        private List<Action> continuationActionList = new List<Action>();

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

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

 

        #region 완료 여부 - IsCompleted

 

        /// <summary>

        /// 완료 여부

        /// </summary>

        public bool IsCompleted

        {

            get

            {

                return this.isCompleted;

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

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

 

        #region 생성자 - TestTask(action)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="action">액션</param>

        public TestTask(Action action)

        {

            this.thread = new Thread

            (

                (ThreadStart)(() =>

                {

                    action();

 

                    this.isCompleted = true;

 

                    foreach(Action continuation in this.continuationActionList)

                    {

                        continuation();

                    }

                }

                )

            );

 

            this.thread.Start();

        }

 

        #endregion

 

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

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

 

        #region 연속 추가하기 - AddContinuation(action)

 

        /// <summary>

        /// 연속 추가하기

        /// </summary>

        /// <param name="action">액션</param>

        public void AddContinuation(Action action)

        {

            this.continuationActionList.Add(action);

        }

 

        #endregion

        #region 대기자 구하기 - GetAwaiter()

 

        /// <summary>

        /// 대기자 구하기

        /// </summary>

        /// <returns>대기자</returns>

        public TestTaskAwaiter GetAwaiter()

        {

            TestTaskAwaiter awaiter = new TestTaskAwaiter(this);

 

            return awaiter;

        }

 

        #endregion

    }

}

 

 

TestTaskAwaiter.cs

 

 

using System;

using System.Runtime.CompilerServices;

 

namespace TestProject

{

    /// <summary>

    /// 테스트 태스크 대기자

    /// </summary>

    public struct TestTaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion

    {

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

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

 

        #region Field

 

        /// <summary>

        /// 태스크

        /// </summary>

        private TestTask task;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

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

 

        #region 완료 여부 - IsCompleted

 

        /// <summary>

        /// 완료 여부

        /// </summary>

        public bool IsCompleted

        {

            get

            {

                return this.task.IsCompleted;

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

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

 

        #region 생성자 - TestTaskAwaiter(task)

 

        /// <summary>

        /// 생성자

        /// </summary>

        /// <param name="task">태스크</param>

        public TestTaskAwaiter(TestTask task)

        {

            this.task = task;

        }

 

        #endregion

 

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

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

 

        #region 결과 구하기 - GetResult()

 

        /// <summary>

        /// 결과 구하기

        /// </summary>

        public void GetResult()

        {

        }

 

        #endregion

        #region 완료시 처리하기 - OnCompleted(continuationAction)

 

        /// <summary>

        /// 완료시 처리하기

        /// </summary>

        /// <param name="continuationAction">연결 액션</param>

        public void OnCompleted(Action continuationAction)

        {

            this.task.AddContinuation(continuationAction);

        }

 

        #endregion

        #region 비관리 완료시 처리하기 - UnsafeOnCompleted(continuationAction)

 

        /// <summary>

        /// 비관리 완료시 처리하기

        /// </summary>

        /// <param name="continuationAction">연결 액션</param>

        public void UnsafeOnCompleted(Action continuationAction)

        {

            this.task.AddContinuation(continuationAction);

        }

 

        #endregion

    }

}

 

 

Program.cs

 

 

using System;

using System.Threading;

using System.Threading.Tasks;

 

namespace TestProject

{

    /// <summary>

    /// 프로그램

    /// </summary>

    class Program

    {

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

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

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

 

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

 

        /// <summary>

        /// 프로그램 시작하기

        /// </summary>

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

        private static async Task Main()

        {

            Console.Title = "커스텀 태스크 사용하기";

 

            await CallAsync2();

 

            Console.WriteLine("비동기 호출 1 완료");

 

            await CallAsync1();

 

            Console.WriteLine("비동기 호출 2 완료");

        }

 

        #endregion

 

        #region 비동기 호출하기 1 - CallAsync1()

 

        /// <summary>

        /// 비동기 호출하기 1

        /// </summary>

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

        private static Task CallAsync1()

        {

            return new TaskFactory().StartNew(() => { Thread.Sleep(5000); });

        }

 

        #endregion

        #region 비동기 호출하기 2 - CallAsync2()

 

        /// <summary>

        /// 비동기 호출하기 2

        /// </summary>

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

        private static TestTask CallAsync2()

        {

            TestTask task = new TestTask(() =>

            {

                Thread.Sleep(5000);

            });

 

            return task;

        }

 

        #endregion

    }

}

 

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

※ Main 함수에서 async를 사용하기 위해서 프로젝트 [속성]의 [빌드] 탭에서 [고급] 버튼을 클릭하고 [고급 빌드 설정] 대화 상자의 [언어 버전] 항목을 "C# 7.1"로 설정해야 한다.

Posted by 사용자 icodebroker

댓글을 달아 주세요