R3でIAsyncEnumerableからストリームを作成する方法です。
Unity 2022.3.28f1
R3 1.2.9
はじめに
R3では非同期メソッド版のObservable.Createを使ってストリームを作成できるようになりました。
これとは別に、IAsyncEnumerableからストリームを作成する方法もあります。
本記事ではこの方法についてまとめます。
使い方
早速使い方です。
using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading; using Cysharp.Threading.Tasks; using R3; using UnityEngine; public sealed class Example : MonoBehaviour { private void Start() { // Observable.CreateFromにIAsyncEnumerableを渡す Observable.CreateFrom(ExampleAsync) .Subscribe(x => { Debug.Log($"OnNext: {x}"); }, result => { Debug.Log($"OnCompleted: {result.IsSuccess}"); }) .AddTo(this); } private static async IAsyncEnumerable<Unit> ExampleAsync( [EnumeratorCancellation] CancellationToken cancellationToken ) { // 1秒ごとに現在時刻を通知、10回で終わり for (var i = 0; i < 10; i++) { await UniTask.Delay(1000, cancellationToken: cancellationToken); yield return Unit.Default; } } }
このケースでは上に記事をリンクしたObservable.Createを使ったものよりもシンプルになっています。
エラーの扱い
IAsyncEnumerableを返すメソッド内でスローされた例外は、OnCompletedに通知されます。
以下のようにコードを変更して再生すると3回通知があった後にIsSuccessがFalseになったOnCompleteが通知されることを確認できます。
using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading; using Cysharp.Threading.Tasks; using R3; using UnityEngine; public sealed class Example : MonoBehaviour { private void Start() { Observable.CreateFrom(ExampleAsync) .Subscribe(x => { Debug.Log($"OnNext: {x}"); }, result => { Debug.Log($"OnCompleted: {result.IsSuccess}"); }) .AddTo(this); } private static async IAsyncEnumerable<Unit> ExampleAsync( [EnumeratorCancellation] CancellationToken cancellationToken ) { for (var i = 0; i < 10; i++) { if (i == 3) { throw new Exception("Error!"); } await UniTask.Delay(1000, cancellationToken: cancellationToken); yield return Unit.Default; } } }