概要
using System; using System.Threading; using Cysharp.Threading.Tasks; using UnityEngine; public class Example : MonoBehaviour { private CancellationTokenSource m_cancellationTokenSource; private void Update() { if ( Input.GetKeyDown( KeyCode.Z ) ) { RunAsync().Forget(); } else if ( Input.GetKeyDown( KeyCode.X ) ) { Debug.Log( "キャンセル" ); m_cancellationTokenSource?.Cancel(); m_cancellationTokenSource = null; } } private async UniTaskVoid RunAsync() { m_cancellationTokenSource = new(); Debug.Log( "開始" ); var cancellationToken = m_cancellationTokenSource.Token; await UniTask .WhenAll( Impl( 1 ), Impl( 2 ), Impl( 3 ) ) .AttachExternalCancellation( cancellationToken ) ; Debug.Log( "完了" ); async UniTask Impl( double seconds ) { Debug.Log( $"開始:{seconds}" ); await UniTask.Delay( TimeSpan.FromSeconds( seconds ) ); Debug.Log( $"完了:{seconds}" ); } } }
AttachExternalCancellation だと UniTask.WhenAll から先には進まなくなるが
UniTask.WhenAll に渡した個々の UniTask は止まらない
using System; using System.Threading; using Cysharp.Threading.Tasks; using UnityEngine; public class Example : MonoBehaviour { private CancellationTokenSource m_cancellationTokenSource; private void Update() { if ( Input.GetKeyDown( KeyCode.Z ) ) { RunAsync().Forget(); } else if ( Input.GetKeyDown( KeyCode.X ) ) { Debug.Log( "キャンセル" ); m_cancellationTokenSource?.Cancel(); m_cancellationTokenSource = null; } } private async UniTaskVoid RunAsync() { m_cancellationTokenSource = new(); Debug.Log( "開始" ); var cancellationToken = m_cancellationTokenSource.Token; await UniTask.WhenAll ( Impl( 1, cancellationToken ), Impl( 2, cancellationToken ), Impl( 3, cancellationToken ) ); Debug.Log( "完了" ); async UniTask Impl( double seconds, CancellationToken cancellationToken ) { Debug.Log( $"開始:{seconds}" ); await UniTask.Delay ( TimeSpan.FromSeconds( seconds ), cancellationToken: cancellationToken ); Debug.Log( $"完了:{seconds}" ); } } }
AttachExternalCancellation を使わずに
UniTask.WhenAll に渡した個々の UniTask に cancellationToken を渡すと
UniTask.WhenAll も個々の UniTask も止まる