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网络类的使用
协程 我们要下载一张图片,加载一个资源,这个时候一定不是一下子就加载好的,或者说我们不一定要等它下载好了才进行其他操作,如果那样的话我就就卡在了下载图片那个地方,傻住了.我们希望我们只要一启动加载的命 ...
随机推荐
- Jquery实现文本框获取焦点清空内容,失去焦点重新获得内容的公共函数
最近在做一个同城交友网站你给我吧(www.niyuewo.com)时写的一个函数与大家分享: //清除input中的内容 $(document).ready(function(){ $("i ...
- LeetCode6 ZigZag Conversion
题意: The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows l ...
- Data Structure 之 KMC字符串匹配算法
有关模式函数值next[i]确实有很多版本啊,在另外一些面向对象的算法描述书中也有失效函数 f(j)的说法,其实是一个意思,即next[j]=f(j-1)+1,不过还是next[j]这种表示法好理解啊 ...
- jquery . fancybox()
1.父页面 function chooseTopic(btn) {//选择议题 $.fancybox({ type : 'iframe', href : '', fitToView : false, ...
- Python 3.4 链接mysql5.7 数据库使用方法
最近笔者在研究Python3.4链接MySQL5.7版本,笔者意图在网上找到一个比较好的链接方式,网上介绍的大致有 mysqldb或者pymssql这两种方法来链接,mysqldb下载地址http:/ ...
- [super dealloc]内存释放的先后顺序
心得:从前做内存释放,只是觉得应该,没体会到这个的重要性,如果不及时释放就会有很多内存泄露,就像我早期遇到的前赴后继的崩溃,比如:没使用完,就释放会崩溃等明显的release问题. 作为全局的 ...
- C Struct Hack
It's not clear if it's legal or portable, but it is rather popular. #include <stdlib.h> #inclu ...
- jQery无缝滚动效果
思路: 赋值所有li,添加到ul末尾,重新计算ul宽度 每次移动一个固定的值,当超出一半时,将ul拉回原位 以下代码 <!DOCTYPE html> <html> <he ...
- Windows XP与Windows 7系统常见漏洞
1.Windows XP系统常见漏洞 Windows XP系统常见的漏洞有UPNP服务漏洞.升级程序漏洞.帮助和支持中心漏洞.压缩文件夹漏洞.服务拒绝漏洞.Windows Media Player漏洞 ...
- cocoapods 卸载,重装,高版本的使用
今天清理下电脑,发现自己电脑上的cocoapods经常出现的一个问题就是一些经常用的第三方库cocoapods搜不到,比如SDWebImage,然后就鼓捣了一下 $pos list 命令发现M 以后的 ...