• Zenject与UniRx结合实现跨线程通信Signal


    •   修改Zenject下ProfileBlock.cs源码, 取消有关UnityEngine.Profiling.Profiler的代码.
    •   然后使用Zenject的Signal:
       // 定义Signal
        public class TestCrossThreadCommEvent : Signal<string, TestCrossThreadCommEvent> { }
    View Code
    1   // Install Signals
    2     Container.DeclareSignal<TestCrossThreadCommEvent>();
    View Code
     1 // 启动线程
     2     tth = new Thread(() =>
     3     {
     4         while (true)
     5         {
     6             Thread.Sleep(1000);
     7             _crossThreadCommEvent.Fire("fire not in main thread");
     8             //_unityEvent.Invoke();
     9         }
    10     });
    11     tth.Start();
    12     // UniRx
    13     _crossThreadCommEvent.AsObservable.ObserveOnMainThread(MainThreadDispatchType.Update)
    14         // 使用lambda表达式是没有问题的
    15         .Subscribe(s => TestCrossThreadComm(s))
    16         .AddTo(this);
    17     
    18     void TestCrossThreadComm(string msg)
    19     {
    20         Debug.Log(Thread.CurrentThread.ManagedThreadId);
    21         Debug.Log(msg);
    22         transform.RotateAround(transform.position, Vector3.up, 5f);
    23     }
    View Code
    •  输出结果:
          1
          UnityEngine.Debug:Log(Object)
          fire not in main thread
          UnityEngine.Debug:Log(Object) 
     
    • 多个参数情况:
    1 // 定义Signal
    2 public class TestCrossThreadCommEvent : Signal<string, string, TestCrossThreadCommEvent> { }
    View Code
    1 // Install Signals
    2 Container.DeclareSignal<TestCrossThreadCommEvent>();
    View Code
     1 // 启动线程
     2 tth = new Thread(() =>
     3 {
     4     while (true)
     5     {
     6         Thread.Sleep(1000);
     7         _crossThreadCommEvent.Fire("fire not in main thread", "	 so happy.");
     8         //_unityEvent.Invoke();
     9     }
    10 });
    11 tth.Start();
    12 // UniRx-Lambda
    13 _crossThreadCommEvent.AsObservable.ObserveOnMainThread(MainThreadDispatchType.Update)
    14     // 使用lambda表达式是没有问题的
    15     .Subscribe(tuple =>
    16     {
    17         Debug.Log(Thread.CurrentThread.ManagedThreadId);
    18         Debug.Log(tuple.Item1 + tuple.Item2);
    19         transform.RotateAround(transform.position, Vector3.up, 5f);
    20     })
    21     .AddTo(this);
    View Code
    •  输出结果:
    1
    UnityEngine.Debug:Log(Object)
    fire not in main thread     so happy.
    UnityEngine.Debug:Log(Object)
     
    以上为Asset Store中Zenject早期版本.
    目前有版本对Signal部分改动如下:
     1 ...
     2 #if UNITY_EDITOR && ZEN_PROFILING_ENABLED
     3             using (ProfileBlock.Start("Signal '{0}'", this.GetType().Name))
     4 #endif
     5             {
     6                 var wasHandled = Manager.Trigger(SignalId, new object[0]);
     7 
     8                 wasHandled |= (_listeners.Count > 0);
     9 
    10                 // Iterate over _tempListeners in case the
    11                 // listener removes themselves in the callback
    12                 // (we use _tempListeners to avoid memory allocs)
    13                 _tempListeners.Clear();
    14 
    15                 for (int i = 0; i < _listeners.Count; i++)
    16                 {
    17                     _tempListeners.Add(_listeners[i]);
    18                 }
    19 
    20                 for (int i = 0; i < _tempListeners.Count; i++)
    21                 {
    22                     var listener = _tempListeners[i];
    23 
    24 #if UNITY_EDITOR && ZEN_PROFILING_ENABLED
    25                     using (ProfileBlock.Start(listener.ToDebugString()))
    26 #endif
    27                     {
    28                         listener();
    29                     }
    30                 }
    31 
    32 #if ZEN_SIGNALS_ADD_UNIRX
    33                 wasHandled |= _observable.HasObservers;
    34 #if UNITY_EDITOR && ZEN_PROFILING_ENABLED
    35                 using (ProfileBlock.Start("UniRx Stream"))
    36 #endif
    37                 {
    38                     _observable.OnNext(Unit.Default);
    39                 }
    40 #endif
    41 ...
    View Code

    涉及到ProfileBlock的使用ZEN_PROFILING_ENABLED来开启, 所以想用Signal跨线程通信,否决掉ZEN_PROFILING_ENABLED就可以了.

  • 相关阅读:
    [一个64位操作系统的设计与实现] 3.1 Func_GetFATEntry疑惑
    【参考】 实现X86_64架构下的BootLoader(二)文件系统
    LBA和CHS转换(转)
    Grafana 重置admin密码
    linux-source: not found ubuntu执行脚本报错
    Hbase学习
    高并发理解
    Linux下安装Artemis
    SpringInAction 第八章 发送异步消息
    SpringInAction 六七章总结
  • 原文地址:https://www.cnblogs.com/linxmouse/p/7500923.html
Copyright © 2020-2023  润新知