zoukankan      html  css  js  c++  java
  • 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就可以了.

  • 相关阅读:
    Docker
    docker
    Go
    Docker4Windows -- 从外部(非本机host)访问 由docker container运行的程序
    Unable to resolve target 'android-9'
    win7中VS2010中安装CSS3.0问题解决方法
    修改vs2005,vs2008,vs2010调试默认浏览器
    Android SDK Content loader has encountered a problem” “parseSdkContent Failed ”
    解决parseSdkContent failed java.lang.NullPointerException错误
    50个Android开发人员必备UI效果源码[转载]
  • 原文地址:https://www.cnblogs.com/linxmouse/p/7500923.html
Copyright © 2011-2022 走看看