はじめに
この記事は下記記事の続きです
【Unity】UniTaskのキャンセル処理(その3)
ThrowIfCancellationRequestedを使用
前回の記事から少し変えたソース(下記)で同様の操作をします
ソースは前回記事のProcess1関数内の
UniTask.DelayにcancelTokenを渡さない
ようにした
cancelToken.ThrowIfCancellationRequested();
を呼ぶようにした
1、Aキーを押すだけ
2、Aキーを押した直後にZキーを押して5秒くらい待機
それぞれどのようなログが出るでしょうか?
public class UniTaskTest1 : MonoBehaviour
{
private CancellationTokenSource cancelTonkenSource = new CancellationTokenSource();
private void Update()
{
if(Input.GetKeyDown(KeyCode.A))
{
this.cancelTonkenSource = new CancellationTokenSource();
this.MainProcess(this.cancelTonkenSource.Token).Forget();
}
else if (Input.GetKeyDown(KeyCode.Z))
{
this.cancelTonkenSource?.Cancel();
}
}
private async UniTask MainProcess(CancellationToken cancelToken)
{
try
{
var val = await this.Process1(cancelToken);
Debug.Log("結果:" + val);
}
catch(OperationCanceledException e)
{
Debug.Log("MainProcess catch");
}
finally
{
Debug.Log("MainProcess finally");
}
}
private async UniTask<int> Process1(CancellationToken cancelToken)
{
try
{
Debug.Log("開始");
int result = -1;
await UniTask.Delay(TimeSpan.FromSeconds(3f));
Debug.Log("待機終了");
cancelToken.ThrowIfCancellationRequested();
result = 1;
if (cancelToken.IsCancellationRequested)
{
Debug.Log("キャンセル2");
return result;
}
result = 2;
return result;
}
catch (OperationCanceledException e)
{
Debug.Log("Process1 catch");
throw;
}
finally
{
Debug.Log("Process1 finally");
}
}
}
正解
まとめ
1は同じなので2を見てみます。
UniTask.DelayにcancelTokenを渡していないので即キャンセルせず待機終了
ログが出てます。
その後キャンセル2
のログは出ず、Catch内に入っていることがログからわかります。
ということは、
キャンセル確認&例外発生は渡されたCancellationTokenのThrowIfCancellationRequested
を呼べばよさそうですね。
ていうか関数名そのままですね。
また、
非同期処理が呼ばれた段階でキャンセルされている可能性だってあるのでまずは関数の先頭でThrowIfCancellationRequestedを呼ぶ
というのが安全そうです!
他にも複数のCancellationTokenリンクさせたりする方法など便利そうなのもあるっぽいのですがいったんここまでです。
ありがとうございました。<(_ _)>