UniRxで処理するスレッドを操作する方法をまとめました。
- Schedulerが指定できるFactoryメソッド
- StartとToAsyncはスレッドプールのSchedulerが使われる
- Observable.CreateとSubscribeOn
- ストリームの途中で処理するスレッドを切り替えるObserveOn
- 関連
unity2019.2.5
Schedulerが指定できるFactoryメソッド
まず、一部のObservableは生成するときに引数としてSchedulerというものが指定できます。
このSchedulerは処理するスレッドを定義するもので、例えば以下のように書けばメインスレッドで処理できます。
using UnityEngine; using UniRx; using System.Threading; using System; public class Example : MonoBehaviour { private void Awake() { Observable .Interval(TimeSpan.FromSeconds(1), Scheduler.MainThread) // メインスレッドを指定 .Subscribe(_ => Debug.Log(Thread.CurrentThread.ManagedThreadId)) .AddTo(this); } }
このSchedulerを以下のように書き換えれば、メインスレッド以外で処理を行うことができます。
using UnityEngine; using UniRx; using System.Threading; using System; public class Example : MonoBehaviour { private void Awake() { Observable .Interval(TimeSpan.FromSeconds(1), Scheduler.ThreadPool) // スレッドプールを指定 .Subscribe(_ => Debug.Log(Thread.CurrentThread.ManagedThreadId)) .AddTo(this); } }
このように、ファクトリメソッドの引数にSchedulerを持つObservableは処理するスレッドを制御できます。
StartとToAsyncはスレッドプールのSchedulerが使われる
Observableのファクトリメソッドに、Start()
やToAsync()
といったものがあります。
これらはサブスレッドでの非同期処理を簡単に書くためのファクトリメソッドです。
仕組みとしては内部的にスケジューラとして前述のScheduler.ThreadPool
が指定されています。
そのため下記のように書くだけで簡単に非同期処理が実現できます。
using UnityEngine; using UniRx; using System.Threading; using System; public class Example : MonoBehaviour { private void Awake() { // サブスレッドでの非同期処理が簡単に書ける Observable.Start(() => Debug.Log(Thread.CurrentThread.ManagedThreadId)) .Subscribe() .AddTo(this); } }
Observable.CreateとSubscribeOn
Observable.Create()
とSubscribeOn()
を組み合わせると指定したスレッドで処理を行うObservableが作れます。
using UnityEngine; using UniRx; using System.Threading; using System; public class Example : MonoBehaviour { private void Awake() { // CreateでObservableを作る Observable.Create<Unit>(observer => { observer.OnNext(Unit.Default); observer.OnCompleted(); return Disposable.Empty; }) // SubscribeOnでスレッドを指定する .SubscribeOn(Scheduler.ThreadPool) .Subscribe(_ => Debug.Log(Thread.CurrentThread.ManagedThreadId)); } }
ストリームの途中で処理するスレッドを切り替えるObserveOn
ObserveOn()
を使うと、ストリームの途中で処理するスレッドを切り替えることができます。
using UnityEngine; using UniRx; using System.Threading; public class Example : MonoBehaviour { private void Awake() { Observable.Start(() => {}) // 別スレッドで開始 .ObserveOnMainThread() // ここからはメインスレッドで処理 .Do(_ => Debug.Log(Thread.CurrentThread.ManagedThreadId)) .ObserveOn(Scheduler.ThreadPool) // ここからはスレッドプールで処理 .Do(_ => Debug.Log(Thread.CurrentThread.ManagedThreadId)) .Subscribe() .AddTo(this); } }