0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity】UniTaskのキャンセル処理(その4)

Last updated at Posted at 2025-04-10

はじめに

この記事は下記記事の続きです
【Unity】UniTaskのキャンセル処理(その3)

ThrowIfCancellationRequestedを使用

前回の記事から少し変えたソース(下記)で同様の操作をします
ソースは前回記事のProcess1関数内の
UniTask.DelayにcancelTokenを渡さないようにした
cancelToken.ThrowIfCancellationRequested();を呼ぶようにした

1、Aキーを押すだけ
2、Aキーを押した直後にZキーを押して5秒くらい待機
それぞれどのようなログが出るでしょうか?

test.cs
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、Aキーを押すだけ
スクリーンショット 2025-04-10 011024.png

2、Aキーを押した直後にZキーを押して5秒くらい待機
スクリーンショット 2025-04-10 011053.png

まとめ

1は同じなので2を見てみます。
UniTask.DelayにcancelTokenを渡していないので即キャンセルせず待機終了ログが出てます。
その後キャンセル2のログは出ず、Catch内に入っていることがログからわかります。

ということは、
キャンセル確認&例外発生は渡されたCancellationTokenのThrowIfCancellationRequestedを呼べばよさそうですね。
ていうか関数名そのままですね。

また、
非同期処理が呼ばれた段階でキャンセルされている可能性だってあるのでまずは関数の先頭でThrowIfCancellationRequestedを呼ぶというのが安全そうです!
 
 
他にも複数のCancellationTokenリンクさせたりする方法など便利そうなのもあるっぽいのですがいったんここまでです。
ありがとうございました。<(_ _)>

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?