对于客户端来说,好的用户体验,需要保持一个快速响应的用户界面。于是便要求:网络请求、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 多线程的更多相关文章

  1. Unity多线程(Thread)和主线程(MainThread)交互使用类——Loom工具分享

    Unity多线程(Thread)和主线程(MainThread)交互使用类——Loom工具分享 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com ...

  2. unity多线程

    多线程概念 多线程,是指实现多个线程并发执行的技术,合理利用多线程可以提升程序的性能,在unity中,一般是避免使用多线程的,unity对多线程的支持并不友好. 协程概念 协程,是指在主线程运行时开启 ...

  3. [Unity]多线程编程的一点心得

    在做毕设的时候涉及到了较大数据的读取,每次从硬盘读都会卡很久,于是找资料之后自己做了个简单的多线程解决方案. 一共有两个类.第一个类ThreadJob如下: using System.Collecti ...

  4. Loom工具使用分享

    Unity多线程(Thread)和主线程(MainThread)交互使用类——Loom工具分享 时间 2014-03-09 11:04:04  ITeye-博客 原文  http://dsqiu.it ...

  5. Unity3D性能优化最佳实践(四)资源审查

    Asset auditing - 资源审查 许多项目发生效能问题的真正原因只是由于人员操作不当或是试东试西,而不小心改到导入设定影响到导入的资源.(例如最近的gitlab惨案) 对于较大规模的项目,最 ...

  6. Unity应用架构设计(10)————绕不开的协程和多线程(Part 1)

    在进入本章主题之前,我们必须要了解客户端应用程序都是单线程模型,即只有一个主线程(Main Thread),或者叫做UI线程,即所有的UI控件的创建和操作都是在主线程上完成的.而服务器端应用程序,也就 ...

  7. Unity应用架构设计(10)——绕不开的协程和多线程(Part 2)

    在上一回合谈到,客户端应用程序的所有操作都在主线程上进行,所以一些比较耗时的操作可以在异步线程上去进行,充分利用CPU的性能来达到程序的最佳性能.对于Unity而言,又提供了另外一种『异步』的概念,就 ...

  8. Unity应用架构设计(10)——绕不开的协程和多线程(Part 1)

    在进入本章主题之前,我们必须要了解客户端应用程序都是单线程模型,即只有一个主线程(Main Thread),或者叫做UI线程,即所有的UI控件的创建和操作都是在主线程上完成的.而服务器端应用程序,也就 ...

  9. 关于Unity中协程、多线程、线程锁、www网络类的使用

    协程 我们要下载一张图片,加载一个资源,这个时候一定不是一下子就加载好的,或者说我们不一定要等它下载好了才进行其他操作,如果那样的话我就就卡在了下载图片那个地方,傻住了.我们希望我们只要一启动加载的命 ...

随机推荐

  1. mysql数据类型区别

    create table t1(c1 float(10,2), c3 decimal(10,2)); insert into t1 values(1234567.23, 1234567.23,1234 ...

  2. LeetCode34 Search for a Range

    题目: Given a sorted array of integers, find the starting and ending position of a given target value. ...

  3. uiview 的transitionWithView 方法使用

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [UIView transitionWithView:_imageV ...

  4. Java中ThreadLocal的设计与使用

    早在Java 1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLocal,给我们在编写多线程程序时提供了一种新的选择.使用这个工具类可以很简洁地编写出优美的多线程程 ...

  5. javaEE学习笔记-单例模式

    定义: 确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式的三要素: (1)私有的静态的成员变量 (2)私有的构造方法 (3)公共的静态的入口点方法 单例模式的分类: (1)饿 ...

  6. 存储过程中的where in实现

    在项目中使用Npoco时发现where in查询总是不能起作用.寻觅了许久终于找到解决方案,特此记录下: ) Set @p='CoreRole,CorePassword,CoreOnlineUser' ...

  7. 单表多次join的sql

    select o1.emp_name as 员工姓名1 , o2.emp_name as 员工姓名2 from tableTest join employee o1 on tabletest.[Emp ...

  8. Java Script基础(二) 基本语法

    一.变量的声明和使用 JavaScript是一种弱类型的语言,没有明确的数据类型,在声明变量时,不需要指定变量的类型,变量的类型由赋给变量的值决定. 变量声明的语法: var 变量名; 示例: var ...

  9. linux_memcached_memcachedb

    三个区别 当你听到memcache与memcached时把它当做是一个东东就好了,尽管它们存在区别,但是这并不影响你对它们的运用及理解. “Memcache”它是一个自由和开放源代码.高性能.分配的内 ...

  10. hdu 4424 并查集

    思路:将边从大到小排序,判断向哪边连,能使总和最大. #include<map> #include<set> #include<cmath> #include< ...