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のキャンセル処理(その3)

Last updated at Posted at 2025-04-10

はじめに

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

Try-Catch-Finallyを使用(Catch内でthrowを呼ぶ)

前回の記事から少し変えたソース(下記)で同様の操作をします
ソースは前回記事のProcess1関数内のreturn 99;throwに変えただけです

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), cancellationToken: cancelToken);
			Debug.Log("待機終了");

			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 004013.png

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

まとめ

1は同じなので2を見てみます。
前回の記事ではMainProcess側のCatch内のログは出ていませんでした。
今回は逆にMainProcess内のTry内の結果ログが出ず、Catch内のログが出ました。
呼び出し元にも例外が発生したと伝えるにはしっかりthrowをする必要がありそうです。

ということは、
・内部で起きた例外は内部で後処理して呼び出し元には成功失敗のみを伝えたいとき
  →戻り値をboolにしてCatch内では必ずFalseで返す、など。
・呼び出し元にも明確に例外が発生したと返す
  →Catch内でしっかりthrowを呼ぶ

これでよさそうですね。

 
でも気になる・・。
今回はUniTask.Delayが例外を出したけど自前の非同期関数でキャンセル時に例外を出すにはどうすれば・・・。
続きは次の記事で

次の記事(続き)
【Unity】UniTaskのキャンセル処理(その4)

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?