Unity主线程和子线程跳转调用(2)

Posted 落叶摆渡知尽秋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity主线程和子线程跳转调用(2)相关的知识,希望对你有一定的参考价值。

  在上一篇介绍了多线程和Unity交互方式,但是由于我的项目是一个unity编辑器插件项目,很显然上一篇的代码需要加以修改,在编辑器下实现Loom.

  1,Editor下的没有Update这个生命周期函数,但是Ediitor提供了EditorApplication.update这个事件,自己用这个事件订阅update方法即可

  2,Editor下的没有Awake OnDestory这些生命周期函数,需要自己编写方法让外部去创建、销毁Loom

  3,  我的项目需要保证子线程逻辑不假死的同时又要保证同步,如下面这段伪代码,执行顺序为:DownFile1->UnityFunction1->DownFile2->UnityFunction2

  

Function
{
    //异步在多线程下运行
    Loom.RunAsync(() =>
    {
        //耗时函数
        DownFile1();

        //回到unity线程继续运行
        Loom.QueueOnMainThread(()=>
        {    
            //这个函数是unity函数
            UnityFunction1();
        }
        
        //耗时函数
        DownFile2();
         //回到unity线程继续运行
        Loom.QueueOnMainThread(()=>
        {    
            //这个函数是unity函数
            UnityFunction2();
        }
    
    }
}

  

  修改后的代码如下

  1 using UnityEngine;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System;
  5 using System.Threading;
  6 using System.Linq;
  7 using UnityEditor;
  8 public class Loom
  9 {
 10     /// <summary>
 11     /// 当前是否有unity任务需要执行
 12     /// </summary>
 13     static bool hasUnityAction = true;
 14 
 15     private static Thread loomThread;
 16 
 17     /// <summary>
 18     /// unity任务表
 19     /// </summary>
 20     private List<Action> actions = new List<Action>();
 21 
 22     #region 单例 注册update事件
 23     private static Loom _instance;
 24     private static readonly object lockObj = new object();
 25     public static Loom Current
 26     {
 27         get
 28         {
 29             if (_instance == null)
 30             {
 31                 lock (lockObj)
 32                 {
 33                     if (_instance == null)
 34                     {
 35                         _instance = new Loom();
 36                     }
 37 
 38                 }
 39             }
 40             return _instance;
 41         }
 42     }
 43     private Loom()
 44     {
 45         EditorApplication.update += Update;
 46 
 47     }
 48     #endregion
 49 
 50 
 51 
 52 
 53     /// <summary>
 54     /// 子线程启动一个任务
 55     /// </summary>
 56     /// <param name="a"></param>
 57     /// <returns></returns>
 58     public Thread RunAsync(Action a)
 59     {
 60         if (loomThread != null)
 61         {
 62             Stop();
 63             throw new Exception("任务仅运行一次");
 64         }
 65         loomThread = new Thread(new ParameterizedThreadStart(RunAction));
 66         loomThread.Name = "Loom线程";
 67         loomThread.Priority = System.Threading.ThreadPriority.Lowest;
 68         loomThread.Start(a);
 69         return loomThread;
 70     }
 71     /// <summary>
 72     /// 加入一个任务到主线程队列
 73     /// </summary>
 74     /// <param name="action"></param>
 75     public void QueueOnMainThread(Action action)
 76     {
 77         if (Current != null && Thread.CurrentThread == loomThread)
 78         {
 79             hasUnityAction = true;
 80             lock (Current.actions)
 81             {
 82                 Current.actions.Add(action);
 83             }
 84             while (hasUnityAction)
 85             {
 86                 loomThread.Priority = System.Threading.ThreadPriority.Lowest;
 87                 Thread.Sleep(10);
 88             }
 89         }
 90 
 91     }
 92 
 93     /// <summary>
 94     /// 延迟子线程
 95     /// </summary>
 96     /// <param name="time"></param>
 97     public void Sleep(int time)
 98     {
 99         if (Current != null && Thread.CurrentThread == loomThread)
100         {
101             Thread.Sleep(time);
102 
103         }
104     }
105 
106     /// <summary>
107     /// 停止任务
108     /// </summary>
109     public void Stop()
110     {
111         EditorApplication.update -= Update;
112         try
113         {
114             loomThread.Abort();
115         }
116         catch (Exception e)
117         {
118             Debug.Log(e.ToString());
119         }
120         finally
121         {
122             loomThread = null;
123             _instance = null;
124         }
125 
126     }
127 
128 
129 
130     private void RunAction(object action)
131     {
132         try
133         {
134             ((Action)action)();
135         }
136         catch
137         {
138         }
139 
140     }
141 
142     List<Action> _currentActions = new List<Action>();
143 
144     static void Update()
145     {
146         try
147         {
148 
149 
150             if (!hasUnityAction) return;
151 
152             lock (Current.actions)
153             {
154                 Current._currentActions.Clear();
155                 Current._currentActions.AddRange(Current.actions);
156                 Current.actions.Clear();
157             }
158             for (int i = 0; i < Current._currentActions.Count; i++)
159             {
160                 Debug.LogError("主线程任务");
161                 Current._currentActions[i]();
162 
163             }
164             hasUnityAction = false;
165         }
166         catch
167         {
168             Debug.LogError("主线程任务失败");
169         }
170     }
171 }

 

以上是关于Unity主线程和子线程跳转调用(2)的主要内容,如果未能解决你的问题,请参考以下文章

通过 Unity 中的后台线程调用主线程中的函数

unity c#跨线程调用怎么实现

android中怎样让main线程和子线程同步一个变量

C++怎么在主线程中使用子线程的数据? 比如说主线程中有一个数组,如何在子线程中调用这个数组

学习java第19天个人总结

主线程怎么给子线程发送消息