unity 多线程
对于客户端来说,好的用户体验,需要保持一个快速响应的用户界面。于是便要求:网络请求、io操作等 开销比较大的操作必须在后台线程进行,从而避免主线程的ui卡顿。(注:协程也是主线程的一部分,进行大量的io操作也会造成UI卡顿)
在 WPF 中,DispatcherObject 只能通过与它关联的 Dispatcher 进行访问。 例如,后台线程不能更新与 UI 线程中的 Dispatcher 关联的 Button 内容。
在unity4.X中,unity的api 是线程不安全的,只允许主线程进行访问。于是,如果在后台线程中想调用unity的api,就必须从后台线程跨回主线程,进行调用。
然而,unity中并不能直接使用 .net中的 dispatcher,或者像android activity中的runOnUiThread 从后台线程 跨回主线程。
那么,unity 多线程中,主线程和后台线程之间通信要用什么方法去实现呢?
1、通过共享数据:
顺序图大致如下,主线程中用携程循环等待,或者在update中进行检测,直到后台线程完成,修改IsFinish=true,主线程再进行对应的逻辑操作。

详见demo中的CZCoroutine文件夹。(注:CZCoroutine为开发群里好友给的一个自己封装协程管理器,并可支持多线程。)
2、实现一个Loom的管理器,将后台线程中需要在主线程中处理的委托添加到 List<Action> _actions中,并在unity的update中进行处理:
public class Loom : MonoBehaviour
{ private static Loom _current; public static Loom Current
{
get
{
if (_current == null && Application.isPlaying)
{ var g = GameObject.Find("Loom");
if (g == null)
{
g = new GameObject("Loom");
} _current = g.GetComponent<Loom>() ?? g.AddComponent<Loom>();
} return _current;
}
} private void Awake()
{
if (_current != null && _current != this)
{
Destroy(gameObject);
}
else
{
_current = this;
}
} private List<Action> _actions = new List<Action>(); public class DelayedQueueItem
{
public float time;
public Action action;
public string name;
} private List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>(); public static void QueueOnMainThread(Action action, float time, string name)
{
lock (Current._delayed)
{
if (Current._delayed.Any(d => d.name == name))
return;
QueueOnMainThread(action, time);
}
} public static void QueueOnMainThread(Action action, string name)
{
QueueOnMainThread(action, , name);
} public static void QueueOnMainThread(Action action, float time)
{
if (time != )
{
lock (Current._delayed)
{
Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = action });
}
}
else
{
lock (Current._actions)
{
Current._actions.Add(action);
}
}
} public static void QueueOnMainThread(Action action)
{
lock (Current._actions)
{
Current._actions.Add(action);
}
} public static void RunAsync(Action a)
{
var t = new Thread(RunAction);
t.Priority = System.Threading.ThreadPriority.Normal;
t.Start(a);
} private static void RunAction(object action)
{
((Action)action)();
} private List<Action> toBeRun = new List<Action>();
private List<DelayedQueueItem> toBeDelayed = new List<DelayedQueueItem>(); private void Update()
{
//Process the non-delayed actions
lock (_actions)
{
toBeRun.AddRange(_actions);
_actions.Clear();
}
foreach (var a in toBeRun)
{
try
{
a();
}
catch (Exception e)
{
Debug.LogError("Queued Exception: " + e.ToString());
}
}
toBeRun.Clear();
lock (_delayed)
{
toBeDelayed.AddRange(_delayed);
}
foreach (var delayed in toBeDelayed.Where(d => d.time <= Time.time))
{
lock (_delayed)
{
_delayed.Remove(delayed);
}
try
{
delayed.action();
}
catch (Exception e)
{
Debug.LogError("Delayed Exception:" + e.ToString());
}
}
toBeDelayed.Clear(); }
}
详见: http://dsqiu.iteye.com/blog/2028503
http://answers.unity3d.com/questions/305882/how-do-i-invoke-functions-on-the-main-thread.html
3、unity多线程插件 Loom
https://www.assetstore.unity3d.com/en/#!/content/7285
这个插件和上面分享的工具类同名,而现在也找不到上面工具类的出处,或许是同个作者,进行了优化,封装拿到unity商店吧。
如果你对C# 中的Thread多线程还不熟悉,推荐 http://www.albahari.com/threading/ 进行学习
unity 多线程的更多相关文章
- Unity多线程(Thread)和主线程(MainThread)交互使用类——Loom工具分享
Unity多线程(Thread)和主线程(MainThread)交互使用类——Loom工具分享 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com ...
- unity多线程
多线程概念 多线程,是指实现多个线程并发执行的技术,合理利用多线程可以提升程序的性能,在unity中,一般是避免使用多线程的,unity对多线程的支持并不友好. 协程概念 协程,是指在主线程运行时开启 ...
- [Unity]多线程编程的一点心得
在做毕设的时候涉及到了较大数据的读取,每次从硬盘读都会卡很久,于是找资料之后自己做了个简单的多线程解决方案. 一共有两个类.第一个类ThreadJob如下: using System.Collecti ...
- Loom工具使用分享
Unity多线程(Thread)和主线程(MainThread)交互使用类——Loom工具分享 时间 2014-03-09 11:04:04 ITeye-博客 原文 http://dsqiu.it ...
- Unity3D性能优化最佳实践(四)资源审查
Asset auditing - 资源审查 许多项目发生效能问题的真正原因只是由于人员操作不当或是试东试西,而不小心改到导入设定影响到导入的资源.(例如最近的gitlab惨案) 对于较大规模的项目,最 ...
- Unity应用架构设计(10)————绕不开的协程和多线程(Part 1)
在进入本章主题之前,我们必须要了解客户端应用程序都是单线程模型,即只有一个主线程(Main Thread),或者叫做UI线程,即所有的UI控件的创建和操作都是在主线程上完成的.而服务器端应用程序,也就 ...
- Unity应用架构设计(10)——绕不开的协程和多线程(Part 2)
在上一回合谈到,客户端应用程序的所有操作都在主线程上进行,所以一些比较耗时的操作可以在异步线程上去进行,充分利用CPU的性能来达到程序的最佳性能.对于Unity而言,又提供了另外一种『异步』的概念,就 ...
- Unity应用架构设计(10)——绕不开的协程和多线程(Part 1)
在进入本章主题之前,我们必须要了解客户端应用程序都是单线程模型,即只有一个主线程(Main Thread),或者叫做UI线程,即所有的UI控件的创建和操作都是在主线程上完成的.而服务器端应用程序,也就 ...
- 关于Unity中协程、多线程、线程锁、www网络类的使用
协程 我们要下载一张图片,加载一个资源,这个时候一定不是一下子就加载好的,或者说我们不一定要等它下载好了才进行其他操作,如果那样的话我就就卡在了下载图片那个地方,傻住了.我们希望我们只要一启动加载的命 ...
随机推荐
- ClamAV
ClamAV 简介以及适用范围 ClamAV是一个在命令行下查毒软件,因为它不将杀毒作为主要功能,默认只能查出您计算机内的病毒,但是无法清除,至多删除文件.ClamAV可以工作很多的平台上,但是有少数 ...
- 关于Android LayoutInflater的解释
LayoutInflater的作用就是动态加载xml布局好的界面,类似于findViewById()来获取已经定义好的控件一样.不同点是LayoutInflater是用来找res/layout/下的x ...
- 计算机网络中的TCP/UDP协议到底是怎么回事(一)
TCP/IP五层网络结构模型 物理层:物理层建立在物理通信介质的基础上,作为系统和通信介质的接口,用来实现数据链路实体间透明的比特 (bit) 流传输.只有该层为真实物理通信,其它各层为虚拟通信 数据 ...
- ios----protocol, optional ,delegate
ios----protocol,delegate protocol——协议 协议是用来定义对象的属性,行为和用于回调的. 协议中有两个关键字@private和@optional,@privat ...
- ios-为银行卡号格式化 每隔四位添加一个空格
-(NSString *)formatterBankCardNum:(NSString *)string { NSString *tempStr=string; NSInteger size =(te ...
- C#三大支柱之多态
1.包含与委托---has-a 2.嵌套类型(枚举.类.接口.结构等) 由于只有嵌套类才可声明为私有,通过嵌套类则可以完全控制内部类型的访问级别. 嵌套类型是包含类的成员,所有可以访问包含类的私有成员 ...
- [Java] SSH框架笔记_S2SH整合步骤
http://tech.ddvip.com/2009-09/1253783051134206.html http://www.blogjava.net/liu0909/archive/2009/07/ ...
- ios菜鸟总结2
这个星期学起oc来可能是最纠结的.话不多说先补充一下上一个星期的快捷键吧.工程导航器:Command+1 显示/隐藏导航器面板:Command+0 .显示/隐藏实用工具面板:Command+Op ...
- 1. SQL Server服务器监控实现方法
对于服务器的监控,和对数据库的监控,很少有合二为一的工具,如果有的话,一般是付费软件,或者自行开发的工具.所以如果不想购买软件,也不想花精力去开发的话,可以结合一些免费/开源的工具.自定义脚本,来完成 ...
- LeetCode 337
House Robber III The thief has found himself a new place for his thievery again. There is only one e ...