2.4 Scheduler
2.4.1 Scheduler 的种类
Scheduler 的名字 | 指定方法 | 说明 |
---|---|---|
ImmediateScheduler | Scheduler.Immediate | 当前线程立刻执行 |
CurrentThreadScheduler | Scheduler.CurrentThread | 当前线程顺序执行 |
ThreadPoolScheduler | Scheduler.ThreadPool | 线程池上执行 |
MainThreadScheduler | Scheduler.MainThread | Unity的主线程上执行(Update) |
IgnoreTimeScaleMainThreadScheduler | Scheduler. MainThreadIgnoreTimeScale | Unity的主线程上,不受TIme.timeScale 影响 |
FixedUpdateMainThreadScheduler | Scheduler. MainThreadFixedUpdate | Unity主线程 (FixedUpdate) |
EndOfFrameMainThreadScheduler | Scheduler. MainThreadEndOfFrame | Unity主线程(EndOfFrame)– |
-
当前线程 指的是上一条消息处理时所处的线程
using System.Threading; using System.Threading.Tasks; using UniRx; using UnityEngine; namespace Sample.Section2.Schedulers { public class CurrentThreadSample : MonoBehaviour { private void Start() { Debug.Log("Unity Main Thread ID:" + Thread.CurrentThread.ManagedThreadId); var subject = new Subject<Unit>(); subject.AddTo(this); subject // OnNext 在当前线程执行 .ObserveOn(Scheduler.Immediate) .Subscribe(_ => { Debug.Log("Thread Id:" + Thread.CurrentThread.ManagedThreadId); }); // 在主线程 发行 OnNext消息 subject.OnNext(Unit.Default); // 别的线程上发行OnNext消息 Task.Run(() => subject.OnNext(Unit.Default)); subject.OnCompleted(); /* *Unity Main Thread ID:1 * Thread Id:1 * Thread Id:79 */ } } }
2.4.2 Scheduler的使用方法
-
使用ObserveOn Operator 对消息的处理时机进行变更
using System.IO; using System.Threading.Tasks; using UniRx; using UnityEngine; namespace Sample.Section2.Schedulers { public class ObserveOnSample : MonoBehaviour { private void Start() { //在线程池上读取文件 var task = Task.Run(() => File.ReadAllText(@"data.txt")); // Task -> Observable 变换 // 这时候线程不变 task.ToObservable() // 这时候切换线程 到 主线程 .ObserveOn(Scheduler.MainThread) .Subscribe(x => { // 到这时线程已经切换 Debug.Log(x); }); } } }
-
工厂方法和Operator 对处理时机的变更
using System; using System.Threading; using UniRx; using Unity.VisualScripting; using UnityEngine; namespace Sample.Section2.Schedulers { public class TimersSample : MonoBehaviour { private void Start() { // 指定MainThread //「1秒后和Update相同的时机执行 」 Observable.Timer(TimeSpan.FromSeconds(1), Scheduler.MainThread) .Subscribe(x => Debug.Log("Scheduler.MainThread " +"经过1秒 " + "Thread Id:" + Thread.CurrentThread.ManagedThreadId)) .AddTo(this); // 默认是 MainThreadScheduler Observable.Timer(TimeSpan.FromSeconds(1)) .Subscribe(x => Debug.Log("Default MainThreadScheduler " + "经过1秒 " + "Thread Id:" + Thread.CurrentThread.ManagedThreadId)) .AddTo(this); // 指定 MainThreadEndOfFrame //「1秒后 在Frame Rendering后 执行 」 Observable.Timer(TimeSpan.FromSeconds(1), Scheduler.MainThreadEndOfFrame) .Subscribe(x => Debug.Log("Scheduler.MainThreadEndOfFrame " +"经过1秒 " + "Thread Id:" + Thread.CurrentThread.ManagedThreadId)) .AddTo(this); // 指定 CurrentThread // 这里实在新做的线程上执行 new Thread(() => { Observable.Timer(TimeSpan.FromSeconds(1), Scheduler.CurrentThread) .Subscribe(x => Debug.Log("new Thread " +"经过1秒 " + "Thread Id:" + Thread.CurrentThread.ManagedThreadId)); //.AddTo(this); }).Start(); /* * new Thread 经过1秒 Thread Id:419 * Scheduler.MainThread 经过1秒 Thread Id:1 * Default MainThreadScheduler 经过1秒 Thread Id:1 * Scheduler.MainThreadEndOfFrame 经过1秒 Thread Id:1 */ } } }
-
MainThreadScheduler 和 在主线程上 CurrentThreadScheduler 的区别
-
MainThreadScheduler 调用的是 WaitForSeconds()
-
CurrentThreadScheduler 调用的是 Thread.Sleep()
-