Unity子线程与主线程交互(委托方式)

Unity  Api无法从子线程访问, 但有些操作(例:IO存取文件)又必须子线程运行, 故实现在子线程做耗时操作, 完成后通知主线程更新状态

事件监听方式, 规避回调地狱:https://blog.csdn.net/qq_34987964/article/details/107318813

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;

/// 
/// 子线程与主线程交互(委托实现)
/// 
public class Loom : MonoBehaviour
{
    private static Loom _instance = null;
    //单例模式(此方法只能在主线程调用)
    public static void Instance()
    {
        if (_instance == null)
        {
            var obj = new GameObject("Loom");
            XLuaManager.DontDestroyOnLoad(obj);
            obj.AddComponent();
        }
    }

    //委托队列
    private Queue asyncQueue = new Queue();
    private Queue mainQueue = new Queue();
    //线程对象
    private Thread thread = null;

    //主线程每次Update执行Function数量
    private static int doUpdate = 5;

    void Awake()
    {
        if (_instance != null)
        {
            DestroyImmediate(gameObject);
            return;
        }
        _instance = this;
        ThreadStart();
    }
    void Update()
    {
        DoFunction();
    }

    //执行Action(根据线程判断对应的方法)
    private void DoFunction()
    {
        if (Thread.CurrentThread == thread)
        {
            if (asyncQueue.Count > 0)
            {
                var func = asyncQueue.Dequeue();
                func();
            }
        }
        else
        {
            if (mainQueue.Count > 0)
            {
                int number = doUpdate;
                do
                {
                    var func = mainQueue.Dequeue();
                    func();
                    number--;
                } while (number > 0 && mainQueue.Count > 0);
            }
        }
    }
    public void AsyncFunction(Action action)
    {
        asyncQueue.Enqueue(action);
    }
    public void MainFunction(Action action)
    {
        mainQueue.Enqueue(action);
    }
    //停止线程
    public void ThreadStop()
    {
        if (thread != null && thread.IsAlive)
        {
            thread.Abort();
            thread = null;
            DestroyImmediate(gameObject);
        }
    }
    void ThreadStart()
    {
        ThreadStop();
        thread = new Thread(new ThreadStart(ThreadDelegate));
        thread.IsBackground = true;
        thread.Start();
    }
    void ThreadDelegate()
    {
        while (this != null)
        {
            DoFunction();
        }
        Debug.Log("Thread Done");
    }
    void OnDestroy()
    {
        Dispose();
    }

    public static void InvokeAsync(Action action)
    {
        if (_instance == null)
        {
            throw new Exception("未实例化Loom对象");
        }
        lock (_instance)
        {
            _instance.AsyncFunction(action);
        }

    }
    public static void InvokeMain(Action action)
    {
        if (_instance == null)
        {
            throw new Exception("未实例化Loom对象");
        }
        lock (_instance)
        {
            _instance.MainFunction(action);
        }
    }
    public static bool IsAlive()
    {
        if (_instance != null)
        {
            lock (_instance)
            {
                return _instance.asyncQueue.Count > 0 || _instance.mainQueue.Count > 0;
            }
        }
        return false;
    }
    public static void Dispose()
    {
        if (_instance != null)
        {
            lock (_instance)
            {
                _instance.asyncQueue.Clear();
                _instance.mainQueue.Clear();
                _instance.ThreadStop();
                Destroy(_instance.gameObject);
                _instance = null;
            }
        }
    }
}

 

你可能感兴趣的:(Unity学习笔记)