Unity에서 효율적인 async / await 및 유용한 비동기 확장 함수를 제공 해주는 오픈 소스
비동기 작업을 동기 작업인 양 효율 적으로 코드 작성이 가능, async/await
Coroutine을 대체가능, 반환 값이 있는 비동기 코드 작성 가능
CancellationTokenSource
CancellationToken
catch (Exception ex) when (!(ex is OperationCanceledException)) // when (ex is not OperationCanceledException) at C# 9.0
SuppressCancellationThrow
//Disable, Destory Cancel 생명 주기 관리 방법 (Destory는 this.CancellationTokenOnDestroy() 대체 가능)
public class MyBehaviour : MonoBehaviour
{
CancellationTokenSource disableCancellation = new CancellationTokenSource();
CancellationTokenSource destroyCancellation = new CancellationTokenSource();
private void OnEnable()
{
if (disableCancellation != null)
{
disableCancellation.Dispose();
}
disableCancellation = new CancellationTokenSource();
}
private void OnDisable()
{
disableCancellation.Cancel();
}
private void OnDestroy()
{
destroyCancellation.Cancel();
destroyCancellation.Dispose();
}
}
취소가 감지 되는 순간 모든 메소드는 throw OperationCanceledException을 상위 함수로 전파한다.
UniTaskScheduler.PropagateOperationCanceledException = false(default: false);
false : 이면 익셉션이 UniTaskScheduler에 전달되고, 로그에 남지않음,
true : 로그가 찍`히고 타입은 UniTaskScheduler.UnobservedExceptionWriteLogType로 결정된다
만약 취소 후 다음 시퀀스를 제어 해주려면 try...catch 구문으로 다음 시퀀스 작업
cts.CancelAfterSlim(TimeSpan.FromSeconds(5));
TimeoutController
TimeoutController timeoutController;
CancellationTokenSource clickCancelSource;
void Start()
{
this.clickCancelSource = new CancellationTokenSource();
this.timeoutController = new TimeoutController(clickCancelSource);
}
var progress = Progress.Create(x => Debug.Log(x));
UniTaskVoid
actEvent += UniTask.Action(async () => { await UniTask.Yield(); });
unityEvent += UniTask.UnityAction(async () => { await UniTask.Yield(); });
await UniTask.WhenAll(
transform.DOMoveX(10, 3).WithCancellation(ct),
transform.DOScale(10, 3).WithCancellation(ct));
await foreach (var _ in UniTaskAsyncEnumerable.EveryUpdate(token))
{
Debug.Log("Update() " + Time.frameCount);
}
await okButton.OnClickAsAsyncEnumerable().Where((x, i) => i % 2 == 0).ForEachAsync(_ =>
{
});
async UniTask TripleClick()
{
using (var handler = button.GetAsyncClickEventHandler())
{
await handler.OnClickAsync();
await handler.OnClickAsync();
await handler.OnClickAsync();
Debug.Log("Three times clicked");
}
}
// use async LINQ
async UniTask TripleClick(CancellationToken token)
{
await button.OnClickAsAsyncEnumerable().Take(3).Last();
Debug.Log("Three times clicked");
}
UniTaskCompletionSource
public UniTask<int> WrapByUniTaskCompletionSource()
{
var utcs = new UniTaskCompletionSource<int>();
// when complete, call utcs.TrySetResult();
// when failed, call utcs.TrySetException();
// when cancel, call utcs.TrySetCanceled();
return utcs.Task; //return UniTask<int>
}
IUniTaskAsyncEnumerable
AsyncReactiveProperty
//Queue(), Subscribe
await button.OnClickAsAsyncEnumerable().ForEachAwaitAsync(async x =>
{
await UniTask.Delay(TimeSpan.FromSeconds(3));
});