はじめに
この記事は下記記事の続きです
【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は同じなので2を見てみます。
前回の記事ではMainProcess側のCatch内のログ
は出ていませんでした。
今回は逆にMainProcess内のTry内の結果ログ
が出ず、Catch内のログ
が出ました。
呼び出し元にも例外が発生したと伝えるにはしっかりthrow
をする必要がありそうです。
ということは、
・内部で起きた例外は内部で後処理して呼び出し元には成功失敗のみ
を伝えたいとき
→戻り値をboolにしてCatch内では必ずFalseで返す、など。
・呼び出し元にも明確に例外が発生した
と返す
→Catch内でしっかりthrowを呼ぶ
これでよさそうですね。
でも気になる・・。
今回はUniTask.Delayが例外を出したけど自前の非同期関数でキャンセル時に例外を出すにはどうすれば・・・。
続きは次の記事で
次の記事(続き)
【Unity】UniTaskのキャンセル処理(その4)