■ 커스텀 태스크 사용하기
------------------------------------------------------------------------------------------------------------------------
▶ TestAsyncTaskMethodBuilder.cs
using System; using System.Runtime.CompilerServices;
namespace TestProject { /// <summary> /// 테스트 비동기 태스크 메소드 빌더 /// </summary> public struct TestAsyncTaskMethodBuilder { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary> /// 비동기 태스크 메소드 빌더 /// </summary> private AsyncTaskMethodBuilder builder;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 태스크 - Task
/// <summary> /// 태스크 /// </summary> public TestTask Task { get { return new TestTask(this.builder.Task); } }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public
#region 생성하기 - Create()
/// <summary> /// 생성하기 /// </summary> /// <returns>테스트 비동기 태스크 메소드 빌더</returns> public static TestAsyncTaskMethodBuilder Create() { return new TestAsyncTaskMethodBuilder { builder = AsyncTaskMethodBuilder.Create() }; }
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Instance //////////////////////////////////////////////////////////////////////////////// Public
#region 결과 설정하기 - SetResult()
/// <summary> /// 결과 설정하기 /// </summary> public void SetResult() { this.builder.SetResult(); }
#endregion #region 예외 설정하기 - SetException(exception)
/// <summary> /// 예외 설정하기 /// </summary> /// <param name="exception">예되</param> public void SetException(Exception exception) { this.builder.SetException(exception); }
#endregion
#region 대기 완료시 처리하기 - AwaitOnCompleted<TAwaiter, TStateMachine>(awaiter, stateMachine)
/// <summary> /// 대기 완료시 처리하기 /// </summary> /// <typeparam name="TAwaiter">대기자 타입</typeparam> /// <typeparam name="TStateMachine">상태 머신 타입</typeparam> /// <param name="awaiter">대기자</param> /// <param name="stateMachine">상태 머신</param> public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine { this.builder.AwaitOnCompleted(ref awaiter, ref stateMachine); }
#endregion #region 비관리 대기 완료시 처리하기 - AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(awaiter, stateMachine)
/// <summary> /// 비관리 대기 완료시 처리하기 /// </summary> /// <typeparam name="TAwaiter">대기자 타입</typeparam> /// <typeparam name="TStateMachine">상태 머신 타입</typeparam> /// <param name="awaiter">대기자</param> /// <param name="stateMachine">상태 머신</param> public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine { this.builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); }
#endregion #region 상태 머신 설정하기 - SetStateMachine(stateMachine)
/// <summary> /// 상태 머신 설정하기 /// </summary> /// <param name="stateMachine">상태 머신</param> public void SetStateMachine(IAsyncStateMachine stateMachine) { this.builder.SetStateMachine(stateMachine); }
#endregion #region 시작하기 - Start<TStateMachine>(stateMachine)
/// <summary> /// 시작하기 /// </summary> /// <typeparam name="TStateMachine">상태 머신 타입</typeparam> /// <param name="stateMachine">상태 머신</param> public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine { this.builder.Start(ref stateMachine); }
#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) { if(this.task.Task == null) { this.task.AddContinuation(continuationAction); } else { this.task.Task.GetAwaiter().OnCompleted(continuationAction); } }
#endregion #region 비관리 완료시 처리하기 - UnsafeOnCompleted(continuationAction)
/// <summary> /// 비관리 완료시 처리하기 /// </summary> /// <param name="continuationAction">연결 액션</param> public void UnsafeOnCompleted(Action continuationAction) { if(this.task.Task == null) { this.task.AddContinuation(continuationAction); } else { this.task.Task.GetAwaiter().UnsafeOnCompleted(continuationAction); } }
#endregion } }
|
▶ TestTask.cs
using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks;
namespace TestProject { /// <summary> /// 테스트 태스크 /// </summary> [AsyncMethodBuilder(typeof(TestAsyncTaskMethodBuilder))] public class TestTask { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary> /// 스레드 /// </summary> private Thread thread;
/// <summary> /// 태스크 /// </summary> private Task task;
/// <summary> /// 완료 여부 /// </summary> private bool isCompleted;
/// <summary> /// 연결 액션 리스트 /// </summary> private List<Action> continuationActionList = new List<Action>();
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 태스크 - Task
/// <summary> /// 태스크 /// </summary> public Task Task { get { return this.task; } }
#endregion #region 완료 여부 - IsCompleted
/// <summary> /// 완료 여부 /// </summary> public bool IsCompleted { get { if(this.thread == null) { return this.task.IsCompleted; }
return this.isCompleted; } }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - TestTask(task)
/// <summary> /// 생성자 /// </summary> /// <param name="task">태스크</param> public TestTask(Task task) { this.task = task; }
#endregion #region 생성자 - TestTask(action)
/// <summary> /// 생성자 /// </summary> /// <param name="action">액션</param> public TestTask(Action action) { this.thread = new Thread((ThreadStart)(() => { action();
this.isCompleted = true;
foreach(Action continuationAction in this.continuationActionList) { continuationAction(); } }));
this.thread.Start(); }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 연결 추가하기 - AddContinuation(action)
/// <summary> /// 연결 추가하기 /// </summary> /// <param name="action">액션</param> public void AddContinuation(Action action) { if(this.thread == null) { this.task.ContinueWith((t) => { action(); }); } else { this.continuationActionList.Add(action); } }
#endregion #region 대기자 구하기 - GetAwaiter()
/// <summary> /// 대기자 구하기 /// </summary> /// <returns>대기자</returns> public TestTaskAwaiter GetAwaiter() { TestTaskAwaiter awaiter = new TestTaskAwaiter(this);
return awaiter; }
#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> private static void Main() { Console.Title = "커스텀 태스크 사용하기";
CallAsync();
Console.ReadKey(false); }
#endregion
#region 비동기 호출하기 1 - CallAsync1()
/// <summary> /// 비동기 호출하기 1 /// </summary> /// <returns>태스크</returns> private static async Task CallAsync1() { await new TaskFactory().StartNew(() => { Thread.Sleep(5000); }); }
#endregion #region 비동기 호출하기 2 - CallAsync2()
/// <summary> /// 비동기 호출하기 2 /// </summary> /// <returns>테스트 태스크</returns> private static async TestTask CallAsync2() { TestTask task = new TestTask(() => { Thread.Sleep(5000); });
await task; }
#endregion #region 비동기 호출하기 - CallAsync()
/// <summary> /// 비동기 호출하기 /// </summary> private static async void CallAsync() { await CallAsync1();
Console.WriteLine("비동기 호출 1 완료");
await CallAsync2();
Console.WriteLine("비동기 호출 2 완료"); }
#endregion } }
|
------------------------------------------------------------------------------------------------------------------------
'C# > Common' 카테고리의 다른 글
[C#/COMMON] WindowsIdentity 클래스 : 윈도우즈 로그인 계정 구하기 (0) | 2019.08.02 |
---|---|
[C#/COMMON] 인증서 설치하기 (0) | 2019.08.02 |
[C#/COMMON] IMessageFilter 인터페이스 : WM_INPUT 메시지 처리하기 (0) | 2019.08.02 |
[C#/COMMON] 지정한 타입의 항목을 갖는 제네릭 리스트 구하기 (0) | 2019.08.01 |
[C#/COMMON] 콘솔(Console) 프로그램 CTRL+C 종료시 처리하기 (0) | 2019.08.01 |
[C#/COMMON] 커스텀 태스크 사용하기 (0) | 2019.08.01 |
[C#/COMMON] 커스텀 태스크 사용하기 (0) | 2019.08.01 |
[C#/COMMON] IAsyncStateMachine 인터페이스 : 비동기 처리하기 (0) | 2019.07.31 |
[C#/COMMON] IAsyncStateMachine 인터페이스 : 비동기 처리하기 (0) | 2019.07.31 |
[C#/COMMON] Environment 클래스 : Is64BitProcess 정적 속성을 사용해 64비트 프로세스 여부 구하기 (0) | 2019.07.31 |
[C#/COMMON] 파일 확장자와 연결된 실행 파일 경로 구하기 (0) | 2019.07.31 |
댓글을 달아 주세요