在上一篇介绍了多线程和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();
} }
}

  

  修改后的代码如下

 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();
}
} } /// <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 = ; i < Current._currentActions.Count; i++)
{
Debug.LogError("主线程任务");
Current._currentActions[i](); }
hasUnityAction = false;
}
catch
{
Debug.LogError("主线程任务失败");
}
}
}

Unity主线程和子线程跳转调用(2)的更多相关文章

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

    Unity除了一些基本的数据类型,几乎所有的API都不能在非unity线程中调用,如果项目中有一段很耗时操作,unity可能会出现“假死”.如果这段操作是和unity无关的,我们可以把这个耗时的操作放 ...

  2. UNIX环境高级编程——主线程与子线程的退出关系

    我们在一个线程中经常会创建另外的新线程,如果主线程退出,会不会影响它所创建的新线程呢?下面就来讨论一下. 1.  主线程等待新线程先结束退出,主线程后退出.正常执行. 示例代码: #include & ...

  3. Android线程之主线程向子线程发送消息

    和大家一起探讨Android线程已经有些日子了,谈的最多的就是如何把子线程中的数据发送给主线程进行处理,进行UI界面的更新,为什么要这样,请查阅之前的随笔.本篇我们就来讨论一下关于主线程向子线程如何发 ...

  4. (转)C#/.NET主线程与子线程之间的关系

    一般 一个应用程序就对应一个进程,一个进程可有一个或多个线程,而一般有一个主线程.       有的博客上说“至少一个主线程”,这一说法持有怀疑         主线程与子线程之间的关系        ...

  5. Handler详解系列(四)——利用Handler在主线程与子线程之间互发消息,handler详解

    MainActivity如下: package cc.c; import android.app.Activity; import android.os.Bundle; import android. ...

  6. C#主线程等待子线程运行结束

    佐左佑右 原文 C#主线程等待子线程运行结束 由于主程序中调用matlab的dll文件进行计算要用较长的时间,主界面会有很长时间的卡顿,造成的用户感受十分不好,因此我想在调用时,将调用放入子线程中,然 ...

  7. Handler具体解释系列(四)——利用Handler在主线程与子线程之间互发消息

    MainActivity例如以下: package cc.c; import android.app.Activity; import android.os.Bundle; import androi ...

  8. Java主线程等待子线程、线程池

    public class TestThread extends Thread { public void run() { System.out.println(this.getName() + &qu ...

  9. [C#参考]主线程和子线程之间的参数传递

    几个进程在大多数情况下要包含很多的子线程,那么他们之间免不了的要互相传递很多的参数,那么参数怎么传递的呢? 主线程向子线程传递参数的方法 第一种方法:Thraed类有一个带参数的委托类型的重载形式,这 ...

随机推荐

  1. (C#)调用Webservice,提示远程服务器返回错误(500)内部服务器错误

    因为工作需要调用WebService接口,查了下资料,发现添加服务引用可以直接调用websevice 参考地址:https://www.cnblogs.com/peterpc/p/4628441.ht ...

  2. sql添加字段说明

    1,sql字段说明 添加 exec sp_addextendedproperty  N'MS_Description', N'主键', N'user', N'dbo', N'table', N'Fre ...

  3. can not connect cube in performancce dashboard

    需要在所有安装sharepoint服务器里面安装ADOMD组件 \Program Files\Microsoft Office Servers\15.0\WebServices\PpsMonitori ...

  4. Weekly Contest 128

    1012. Complement of Base 10 Integer Every non-negative integer N has a binary representation.  For e ...

  5. 【文文殿下】CF1098C Construct a tree 题解

    题解 挺水的一道题. Rating $ \color{orange} {2300}$ 以下送命题. 首先我们知道,所有子树大小之和就是节点个数加上从根到所有节点的路径长度之和. 他要求度数尽可能小,所 ...

  6. 洛谷P4197 Peaks&&克鲁斯卡尔重构树学习笔记(克鲁斯卡尔重构树+主席树)

    传送门 据说离线做法是主席树上树+启发式合并(然而我并不会) 据说bzoj上有强制在线版本只能用克鲁斯卡尔重构树,那就好好讲一下好了 这里先感谢LadyLex大佬的博客->这里 克鲁斯卡尔重构树 ...

  7. django-ORM相关代码及其sql执行次数

    1.普通情况:通过log可以看出,这种情况下,访问了1次数据库 def test(request): """测试连表""" users = ...

  8. 静态分析第三发 so文件分析(小黄人快跑)

    本文作者:i春秋作家——HAI_ 0×00 工具 1.IDA pro 2.Android Killer 0×01 环境 小黄人快跑 下载地址http://download.csdn.net/downl ...

  9. Android安全防护防护———加密算法

    摘要 这篇文章本来早就应该写了,但是由于项目一直开发新的需求,就拖后了.现在有时间了,必须得写了.现在Android应用程序对安全防范这方面要求越来越高了.特别是金融行业,如果金融app没有没有做好相 ...

  10. python 初步认识Flask

    1.简介 flask 问题一:  访问百度的流程? a. 客户端: 发送请求报文,  请求行, 请求头, 请求体 b.服务端: 解析请求的报文, 解析域名, 进行路由匹配分发找到对应的视图函数, 打包 ...