何が原因でUniTaskがキャンセルされたのか区別する方法
目的
UniTaskがキャンセルされた文脈に応じて、処理を変えたい。
キャンセル原因を区別する方法を記述する。
方法
- 文脈ごとにCancellationToken(以下Token)を用意する
- LinkedTokenを利用して、複数のTokenを1つのTokenにする
- LinkedTokenを非同期関数に渡す。
- 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で区別する振る舞いを期待する実装になっているため。