🌥制作記録🌥

創作に関することを書いていきます。だいたいゲーム系

何が原因でUniTaskがキャンセルされたのか区別する方法

目的

UniTaskがキャンセルされた文脈に応じて、処理を変えたい。

キャンセル原因を区別する方法を記述する。

方法

  1. 文脈ごとにCancellationToken(以下Token)を用意する
  2. LinkedTokenを利用して、複数のTokenを1つのTokenにする
  3. LinkedTokenを非同期関数に渡す。
  4. try-catch内にてcatchするOperationCanceledException例外からTokenを取得し、区別する。

コード例

        private async void Start()
        {
            _keyboardACts = new CancellationTokenSource();
            _keyboardBCts = new CancellationTokenSource();
            var linkedTs = CancellationTokenSource.CreateLinkedTokenSource(_keyboardACts.Token, _keyboardBCts.Token);
            try
            {
                await UniTask.Delay(10000, DelayType.Realtime, PlayerLoopTiming.Update, linkedTs.Token);
            }
            catch (OperationCanceledException e) when (e.CancellationToken == linkedTs.Token)
            {
                if (_keyboardACts.Token.IsCancellationRequested)
                    Debug.Log("cancel from keyboard a");
                else if (_keyboardBCts.Token.IsCancellationRequested)
                    Debug.Log("cancel from keyboard b");
            }
        }

        private void Update()
        {
            if (Input.GetKeyDown(KeyCode.A))
                _keyboardACts.Cancel();
            else if (Input.GetKeyDown(KeyCode.B)) 
                _keyboardBCts.Cancel();
        }

おまけ

新規例外を定義して区別していない理由は、ライブラリ自体がTokenで区別する振る舞いを期待する実装になっているため。