using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;

public class Haligali : MonoBehaviour
{
[SerializeField] private float duration = 0.1f;
private CancellationTokenSource _cancellationTokenSource;
private CancellationToken Token => _cancellationTokenSource.Token;
private bool IsRunning => _cancellationTokenSource != null;

public void Trigger()
{
if (IsRunning)
{
_cancellationTokenSource.Cancel();
}
else
{
RunInternal();
}
}

private async void RunInternal()
{
_cancellationTokenSource = new CancellationTokenSource();

// try catch ๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒƒ์€ cancellation token์ด ์บ”์Šฌ๋˜๋Š” ๊ฒƒ์„ ๊ฐ์ง€ํ•˜๊ธฐ ์œ„ํ•จ์ž„.
try
{
await UniTask.Delay(TimeSpan.FromSeconds(duration), cancellationToken: Token);
Debug.Log("process done");
}
catch
{
Debug.Log("process cancelled");
}

// ํ† ํฐ์ด ์บ”์Šฌ๋˜์—ˆ๋Š”์ง€์™€๋Š” ์ƒ๊ด€์—†์ด ํ•จ์ˆ˜ ์ข…๋ฃŒ์‹œ ํ† ํฐ์„ dispose ํ•  ํ•„์š”๊ฐ€ ์žˆ์Œ.
_cancellationTokenSource.Dispose();
_cancellationTokenSource = null;
}

// ์Šคํƒ€ํŠธํ•จ์ˆ˜์—์„œ ํ…Œ์ŠคํŠธ ์‹œ์ž‘
private void Start()
{
Test();
}

// ํ…Œ์ŠคํŠธ์šฉ ํ•จ์ˆ˜
private async void Test()
{
// process cancelled (์ด๋ก ์ ์œผ๋กœ ๋™์‹œ์— ํŠธ๋ฆฌ๊ฑฐ ๋  ๊ฒฝ์šฐ)
Trigger();
Trigger();

// process cancelled
Trigger();
await UniTask.Delay(TimeSpan.FromSeconds(0.01f));
Trigger();

// process cancelled
Trigger();
await UniTask.Delay(TimeSpan.FromSeconds(0.05f));
Trigger();

// process cancelled
Trigger();
await UniTask.Delay(TimeSpan.FromSeconds(0.1f));
Trigger();

// process done
Trigger();
await UniTask.Delay(TimeSpan.FromSeconds(0.2f));
Trigger();
}
}

์œ ๋‹ˆํƒœ์Šคํฌ ์“ฐ๋Š”๊ฒƒ๋„ ํ•จ ๊ฒ€ํ† ํ•ด๋ด ๋‚ด๊ฐ€ ์š”์ฆ˜ ์ž์ฃผ์“ฐ๋Š” ํŒจํ„ด์ธ๋ฐ ์ด๊ฑฐ ์ข‹์€๊ฑด์ง€๋Š” ๋‚˜๋„ ๋ชฐ๋ฆ„.

๊ณ ์ˆ˜๋“ค ์žˆ์œผ๋ฉด ์ด๊ฑฐ ๊ดœ์ฐฎ์€์ง€๋„ ๋‹ต๋ณ€ ๋ถ€ํƒํ•จ.

์•ฝ๊ฐ„ ๊ฝ๊ธฐํ•œ๊ฑฐ๋Š” ํ† ํฐ์„ ๋งค๋ฒˆ new๋กœ ๋งŒ๋“ค์–ด์ฃผ๋Š”๊ฑด๋ฐ ์ด๊ฑฐ๋ง๊ณ ๋Š” ๋ชจ๋ฅด๊ฒ ์Œ.

์ฝ”๋“œ์˜ ์•„์ด๋””์–ด๋Š”ย 

1. cancellationToken์„ ์ƒˆ๋กœ ๋งŒ๋“ค๊ณ  0.1์ดˆ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ disposeํ•˜๋Š” ๋น„๋™๊ธฐํ•จ์ˆ˜๊ฐ€ ์žˆ๊ณ 

ย  1-1. ํ† ํฐ์ด ์ทจ์†Œ๋˜๋ฉด, ์ทจ์†Œ ํ•จ์ˆ˜ ํ˜ธ์ถœ (์—ฌ๊ธฐ์„œ๋Š” catch ์•ˆ์˜ย Debug.Log("process cancelled");)

ย  1-1. UniTask.Delay ๋น„๋™๊ธฐย ํ•จ์ˆ˜ ์™„๋ฃŒ ์ดํ›„, ์™„๋ฃŒ ํ•จ์ˆ˜ ํ˜ธ์ถœ (์—ฌ๊ธฐ์„œ๋Š” tryย ์•ˆ์˜ย Debug.Log("process done");)

2. cancellationToken์ด ์žˆ์œผ๋ฉด ํ•ด๋‹น ํ† ํฐ์„ ์ทจ์†Œํ•˜๊ธฐ, ์—†์œผ๋ฉด 1๋ฒˆ์˜ ๋น„๋™๊ธฐํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋Š” ํ•จ์ˆ˜


๋นˆ ๊ฒŒ์ž„์˜ค๋ธŒ์ ํŠธ์— ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ๋‹ฌ๊ณ  ์‹คํ–‰ํ•˜๋ฉด Testํ•จ์ˆ˜ ์‹คํ–‰ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Œ.

์ผ๋‹จ์€ ๋‚ด ํ™˜๊ฒฝ์—์„œ๋Š” ์ž˜ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Œ.