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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM