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

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

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

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

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

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

Function

{

    //异步在多线程下运行

    Loom.RunAsync(() =>

    {

        //耗时函数

        DownFile1();

        //回到unity线程继续运行

        Loom.QueueOnMainThread(()=>

        {   

            //这个函数是unity函数

            UnityFunction1();

        }

         

        //耗时函数

        DownFile2();

         //回到unity线程继续运行

        Loom.QueueOnMainThread(()=>

        {   

            //这个函数是unity函数

            UnityFunction2();

        }

     

    }

}

  

  修改后的代码如下

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Threading;
using System.Linq;
using UnityEditor;
public class Loom
{
    /// <summary>
    /// 当前是否有unity任务需要执行
    /// </summary>
    static bool hasUnityAction = true;

    private static Thread loomThread;

    /// <summary>
    /// unity任务表
    /// </summary>
    private List<Action> actions = new List<Action>();

    #region 单例 注册update事件
    private static Loom _instance;
    private static readonly object lockObj = new object();
    public static Loom Current
    {
        get
        {
            if (_instance == null)
            {
                lock (lockObj)
                {
                    if (_instance == null)
                    {
                        _instance = new Loom();
                    }

                }
            }
            return _instance;
        }
    }
    private Loom()
    {
        EditorApplication.update += Update;

    }
    #endregion




    /// <summary>
    /// 子线程启动一个任务
    /// </summary>
    /// <param name="a"></param>
    /// <returns></returns>
    public Thread RunAsync(Action a)
    {
        if (loomThread != null)
        {
            Stop();
            throw new Exception("任务仅运行一次");
        }
        loomThread = new Thread(new ParameterizedThreadStart(RunAction));
        loomThread.Name = "Loom线程";
        loomThread.Priority = System.Threading.ThreadPriority.Lowest;
        loomThread.Start(a);
        return loomThread;
    }
    /// <summary>
    /// 加入一个任务到主线程队列
    /// </summary>
    /// <param name="action"></param>
    public void QueueOnMainThread(Action action)
    {
        if (Current != null && Thread.CurrentThread == loomThread)
        {
            hasUnityAction = true;
            lock (Current.actions)
            {
                Current.actions.Add(action);
            }
            while (hasUnityAction)
            {
                loomThread.Priority = System.Threading.ThreadPriority.Lowest;
                Thread.Sleep(10);
            }
        }

    }

    /// <summary>
    /// 延迟子线程
    /// </summary>
    /// <param name="time"></param>
    public void Sleep(int time)
    {
        if (Current != null && Thread.CurrentThread == loomThread)
        {
            Thread.Sleep(time);

        }
    }

    /// <summary>
    /// 停止任务
    /// </summary>
    public void Stop()
    {
        EditorApplication.update -= Update;
        try
        {
            loomThread.Abort();
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
        }
        finally
        {
            loomThread = null;
            _instance = null;
        }

    }



    private void RunAction(object action)
    {
        try
        {
            ((Action)action)();
        }
        catch
        {
        }

    }

    List<Action> _currentActions = new List<Action>();

    static void Update()
    {
        try
        {


            if (!hasUnityAction) return;

            lock (Current.actions)
            {
                Current._currentActions.Clear();
                Current._currentActions.AddRange(Current.actions);
                Current.actions.Clear();
            }
            for (int i = 0; i < Current._currentActions.Count; i++)
            {
                Debug.LogError("主线程任务");
                Current._currentActions[i]();

            }
            hasUnityAction = false;
        }
        catch
        {
            Debug.LogError("主线程任务失败");
        }
    }
}

原文:Unity主线程和子线程跳转调用(2) - 落叶摆渡知尽秋 - 博客园

猜你喜欢

转载自blog.csdn.net/weixin_42565127/article/details/124757018