본문 바로가기
개발/Unity

Unity) 순차적인 Task 처리하기 위한 유틸 코드

by 테샤르 2024. 12. 18.

순차적인 Task 처리하기 위한 유틸 코드

 

작업을 하다보면 async 형태로 작업을 하는 Task 코드를 사용하는 과정에서

순차적인 순서에 대한 보장을 하는 코드가 필요할때가 있다.

 

예를 들어서 선행 처리가 보장되어야하는 항목들로

예시를들면 광고를 노출시키는 과정에서 다음과 같은 선행이 필요하다.

 

광고 SDK 로드 -> 광고 로드 -> 광고 시청 -> 광고 종료

다음과 같은 형태의 코드를 보장하기 위해서 여러가지 방법으로 작업이 가능한데 순차적인 Task를 보장하는 코드를 간단하게 만들어 보았다.

 

반응형

 

<TaskCain 코드>

public class TaskChain : Singleton<TaskChain>
{
    private readonly List<Func<CancellationToken, Task>> _taskList = new();
    private readonly CancellationTokenSource _cts = new();
    private readonly object _lock = new();

    public TaskChain Add(Func<CancellationToken, Task> taskFunc)
    {
        lock (_lock)
        {
            _taskList.Add(taskFunc);
        }
        return this;
    }

    public async Task ExecuteAsync()
    {
        try
        {
            List<Func<CancellationToken, Task>> taskListCopy;

            lock (_lock)
            {
                // 복사본 생성
                taskListCopy = new List<Func<CancellationToken, Task>>(_taskList);
            }

            foreach (var taskFunc in taskListCopy)
            {
                _cts.Token.ThrowIfCancellationRequested();

                await taskFunc(_cts.Token);
            }
        }
        catch (Exception ex)
        {
            Debug.LogError($"TaskChain encountered an error: {ex.Message}");
            Cancel();
            throw;
        }
    }

    public void Cancel()
    {
        if (!_cts.IsCancellationRequested)
        {
            _cts.Cancel();
            Debug.Log("TaskChain canceled.");
        }
    }

    public void Clear()
    {
        lock (_lock)
        {
            _taskList.Clear();
        }
        Debug.Log("TaskChain cleared.");
    }

    public void Dispose()
    {
        _cts.Dispose();
    }
}

 

 

< 사용 예시> 

// Example usage
public class TaskChainExample : MonoBehaviour
{
    private async void Start()
    {
        var taskChain = new TaskChain();

        taskChain
            .Add(async token =>
            {
                Debug.Log("Task 1 started.");
                await Task.Delay(1000, token); // Simulates some async work
                Debug.Log("Task 1 completed.");
            })
            .Add(async token =>
            {
                Debug.Log("Task 2 started.");
                await Task.Delay(1000, token);
                Debug.Log("Task 2 completed.");
            })
            .Add(async token =>
            {
                Debug.Log("Task 3 started.");
                await Task.Delay(1000, token);
                Debug.Log("Task 3 completed.");
            });

        try
        {
            await taskChain.ExecuteAsync();
        }
        catch (Exception ex)
        {
            Debug.LogError($"Error during task chain execution: {ex.Message}");
        }
        finally
        {
            taskChain.Dispose();
        }
    }
}

 

순차적으로 처리가 되어야하는 Task 형태의 유틸 코드이다.

 

 

★☆☆☆☆

 

반응형

댓글