【Unity】awaitやForgetを使用しないでUniTaskを起動するとタスクがメモリリークしてしまう現象の解決方法

はじめに

今回はawaitやForgetを使用しないでUniTaskを起動するとタスクがメモリリークしてしまう現象の解決方法を紹介します

環境は Unity 2021.3.25f1です

解決方法

下記のようにawaitやForgetを使用しないでUniTaskを起動するとタスクがメモリリークしてしまう

using System.Collections.Generic;
using UnityEngine;
using Cysharp.Threading.Tasks;
using System.Threading;
public class Test : MonoBehaviour
{
  

    async UniTaskVoid Update()
    {
        if(Input.GetKeyDown(KeyCode.F))
        {

            var task = TestFnuc(this.GetCancellationTokenOnDestroy());        
        }
    }

    async UniTask TestFnuc(CancellationToken Token)
    {
        Token.ThrowIfCancellationRequested();
        await UniTask.DelayFrame(120,cancellationToken: Token);
    }
}

解決方法としてはAttachExternalCancellationを使用してCancellationTokenを登録することでタスクが正常に解放されます

    async UniTaskVoid Update()
    {
        if(Input.GetKeyDown(KeyCode.F))
        {
           //awaitやforget()を使用しないでUniTaskを呼ぶ場合は
           //AttachExternalCancellation(this.GetCancellationTokenOnDestroy()を呼ばないと
           //タスクが解放されない
            var task = TestFnuc(this.GetCancellationTokenOnDestroy()).AttachExternalCancellation(this.GetCancellationTokenOnDestroy());//TestFnuc起動         
        }
    }

公式的にはあまり使用してほしくはないみたいなので利用する際は本当に必要か検討しましょう

neue.cc

解決方法?

System.GC.Collect()を呼べばTaskのStatusがSucceededやCanceledを無理やり開放することができます