using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading.Tasks; // Task
public class TaskExample : MonoBehaviour
{
/* Task Method
* Factory.StartNew(): 스레드를 생성과 동시에 시작
* Start(): Task 스레드 시작
* Wait(): Task 끝날 때까지 대기
* **/
void Start()
{
// 직접 호출, 스레드 생성 및 시작
Task.Factory.StartNew( () => { Debug.Log( "Task" ); } );
// Action
Task task2 = new Task( new System.Action( DebugLog ) );
task2.Start();
// delegate 대리자
Task task3 = new Task( delegate { DebugLog(); } );
task3.Start();
// 람다식
Task task4 = new Task( () => DebugLog() );
task4.Start();
// 람다와 익명 메서드
Task task5 = new Task( () => { DebugLog(); });
task5.Start();
// 각 Task가 끝날 때까지 대기
// 대기하지 않으면 Main이 먼저 끝나서 결과를 보지 못함
task2.Wait();
task3.Wait();
task4.Wait();
task5.Wait();
}
void DebugLog()
{
Debug.Log("Task");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading.Tasks; // Task
public class GenericTaskExample : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Task<int> intTask = Task.Factory.StartNew<int>( () => GetSize( "GenericTask " ) );
/*
* 메인 스레드에서 다른 작업 실행
*/
int result = intTask.Result;
Debug.Log( result );
}
int GetSize( string data )
{
return data.Length;
}
}
위 경우는 Task에서 리턴값을 꼭 받아야 하는데
그 작업이 무거울 경우 /메인 스레드에서 다른 작업 실행/ 을 활용하여
메인 스레드에게 다른 일을 시키면 좋다고 한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
using System.Threading.Tasks;
public class CancellationTokenExample : MonoBehaviour
{
// 1. 클래스 멤버로 CancellationTokenSource 선언
CancellationTokenSource m_CancelTokenSource;
Task<int> m_Task;
void Start()
{
// 2. CancellationTokenSource 객체 생성
m_CancelTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = m_CancelTokenSource.Token;
m_Task = Task.Factory.StartNew(TaskMethod, cancellationToken);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.C))
{
// CancellationTokenSource 의 Cancel() 를 통해 작업 취소
m_CancelTokenSource.Cancel();
if(m_Task != null)
{
Debug.Log( $"Count: {m_Task.Result}" );
}
}
}
private int TaskMethod()
{
int count = 0;
for (int i = 0; i < 10; i++)
{
// 비동기 작업 메서드 안에서 작업이 취소되었는지 체크
if (m_CancelTokenSource.Token.IsCancellationRequested)
{
break;
}
++count;
Thread.Sleep( 1000 );
}
return count;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
using System.Threading.Tasks;
public class AsyncAwaitExample : MonoBehaviour
{
/* Async, Await Method
* Run(): 비동기 시작
* FromResult(): 비동기 시작 후 결과값을 얻음 */
void Start()
{
TaskRun();
TaskFromResult();
}
async void TaskRun()
{
var task = Task.Run( () => TaskRunMethod( 3 ) );
int count = await task;
Debug.Log( $"Count: {task.Result}" );
}
private int TaskRunMethod(int limit)
{
int count = 0;
for (int i = 0; i < limit; i++)
{
++count;
Thread.Sleep( 1000 );
}
return count;
}
async void TaskFromResult()
{
int sum = await Task.FromResult( Add(1, 2) );
Debug.Log( sum );
}
private int Add(int a, int b)
{
return a + b;
}
}