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();
} }
}
修改后的代码如下
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)的更多相关文章
- Unity主线程和子线程跳转调用(1)
Unity除了一些基本的数据类型,几乎所有的API都不能在非unity线程中调用,如果项目中有一段很耗时操作,unity可能会出现“假死”.如果这段操作是和unity无关的,我们可以把这个耗时的操作放 ...
- UNIX环境高级编程——主线程与子线程的退出关系
我们在一个线程中经常会创建另外的新线程,如果主线程退出,会不会影响它所创建的新线程呢?下面就来讨论一下. 1. 主线程等待新线程先结束退出,主线程后退出.正常执行. 示例代码: #include & ...
- Android线程之主线程向子线程发送消息
和大家一起探讨Android线程已经有些日子了,谈的最多的就是如何把子线程中的数据发送给主线程进行处理,进行UI界面的更新,为什么要这样,请查阅之前的随笔.本篇我们就来讨论一下关于主线程向子线程如何发 ...
- (转)C#/.NET主线程与子线程之间的关系
一般 一个应用程序就对应一个进程,一个进程可有一个或多个线程,而一般有一个主线程. 有的博客上说“至少一个主线程”,这一说法持有怀疑 主线程与子线程之间的关系 ...
- Handler详解系列(四)——利用Handler在主线程与子线程之间互发消息,handler详解
MainActivity如下: package cc.c; import android.app.Activity; import android.os.Bundle; import android. ...
- C#主线程等待子线程运行结束
佐左佑右 原文 C#主线程等待子线程运行结束 由于主程序中调用matlab的dll文件进行计算要用较长的时间,主界面会有很长时间的卡顿,造成的用户感受十分不好,因此我想在调用时,将调用放入子线程中,然 ...
- Handler具体解释系列(四)——利用Handler在主线程与子线程之间互发消息
MainActivity例如以下: package cc.c; import android.app.Activity; import android.os.Bundle; import androi ...
- Java主线程等待子线程、线程池
public class TestThread extends Thread { public void run() { System.out.println(this.getName() + &qu ...
- [C#参考]主线程和子线程之间的参数传递
几个进程在大多数情况下要包含很多的子线程,那么他们之间免不了的要互相传递很多的参数,那么参数怎么传递的呢? 主线程向子线程传递参数的方法 第一种方法:Thraed类有一个带参数的委托类型的重载形式,这 ...
随机推荐
- C# 泛型实现Table与实体的相互转换
public class ModelHandler<T> where T : new() { /// <summary> /// Table转换成实体 /// </sum ...
- T-SQL判断是否存在表、临时表
利用SQL SERVER的系统函数 object_id() 可以判断是否存在表.临时表, object_id() 的作用是返回架构范围内对象的数据库对象标识.(即返回系统视图 sys.objects ...
- UE4随笔 二 第一印象
打开UE4,短暂的兴奋过后,开始大概扫一扫UE4的编辑器,整个界面比UE3更有现代气息: 之前看其他人写的文章,虚幻4最重要的改动集中在下面几个方向上: 跨平台: WIN和MAC平台都能使用,这就意味 ...
- MYsql 之单标查询.
http://www.cnblogs.com/wangfengming/articles/8064956.html .数据操作 .增 INSERT into t2(name,age) VALUES() ...
- ASP.NET Core获取客户端IP地址
1.在ConfigureServices注入IHttpContextAccessor // ASP.NET Core 2.1的注入方式 //services.AddHttpContextAccesso ...
- 20164321 王君陶 Exp1 PC平台逆向破解
一.实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同时包含另一个代码片段,getS ...
- Chrome浏览器插件开发-淘宝自动登录
浏览器插件的介绍 Chrome浏览器插件开发的准备工作 manifest.json配置介绍 页面如何注入scripts文件 一. 浏览器插件的介绍 浏览器插件是一种遵循一定规范的应用程序接口编写出来的 ...
- Python os.walk() 遍历出当前目录下的文件夹和文件
os.walk目录遍历 os.walk的参数如下: os.walk(top, topdown=True, onerror=None, followlinks=False) 其中: - top是要遍历的 ...
- Js验证15/18身份证
var vcity={ 11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古&quo ...
- POJ 1095
#include <iostream> #define MAXN 20 using namespace std; __int64 cat[MAXN]; int sum; void give ...