UniRx_UniTask_学习记录_2.4_Scheduler

本文介绍了不同类型的Scheduler及其在Unity中的应用,包括ImmediateScheduler、CurrentThreadScheduler等,并通过示例展示了如何使用ObserveOn操作符来改变消息处理的时间点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2.4 Scheduler

2.4.1 Scheduler 的种类

Scheduler 的名字指定方法说明
ImmediateSchedulerScheduler.Immediate当前线程立刻执行
CurrentThreadSchedulerScheduler.CurrentThread当前线程顺序执行
ThreadPoolSchedulerScheduler.ThreadPool线程池上执行
MainThreadSchedulerScheduler.MainThreadUnity的主线程上执行(Update)
IgnoreTimeScaleMainThreadSchedulerScheduler.
MainThreadIgnoreTimeScale
Unity的主线程上,不受TIme.timeScale 影响
FixedUpdateMainThreadSchedulerScheduler.
MainThreadFixedUpdate
Unity主线程 (FixedUpdate)
EndOfFrameMainThreadSchedulerScheduler.
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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值