这是我google unity3D一个问题偶然发现的在stackflow上非常有趣的帖子:

大意是 要在unity3D上从server下载一个zip,并解压到持久化地址.并将其载入到内存中.以下展示了这样的使用方法:

IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
ExtractZip();
yield return StartCoroutine(LoadZipContent());
}

可是ExtractZip()方法是同步的,这将挂起进程.结果是不管怎样试图解压zip,进程将会被杀死.我觉得是主线程太久没有响应,所以被os杀死.

所以我猜想将提取zip放在单独线程可能会解决这个问题,并且看起来这样奏效了.我写了这样一个类:

public class ThreadedAction
{
public ThreadedAction(Action action)
{
var thread = new Thread(() => {
if(action != null)
action();
_isDone = true;
});
thread.Start();
} public IEnumerator WaitForComplete()
{
while (!_isDone)
yield return null;
} private bool _isDone = false;
}

如此用它:

IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
var extractAction = new ThreadedAction(ExtractZip);
yield return StartCoroutine(extractAction.WaitForComplete());
yield return StartCoroutine(LoadZipContent());
}

可是我仍旧不确定这是不是最好的解决的方法.我是否须要锁定_isDone(not too used to multithreading).

楼主已经给出解决方法了,原来在球完美之道,哈哈.

以下的跟帖是:

这真是在协程里糅合多线程的优雅方案.做得好!

Mixing coroutines and threads is perfectly safe, provided you correctly lock access to resources shared between your main thread (which the coroutine executes on) and the worker thread(s) you create. You shouldn't need to lock _isDone in any way, since it's
only ever written to by the worker thread and there's no intermediate state that could cause the main thread to misbehave.

混合协程和线程是全然线程安全的,它为了正确锁定主线程(协程所在的)和工作线程(可能多个)的共享资源.你不须要锁定_isDone.由于它仅仅会在工作线程中写,没有交替状态会引起主线程误解.

你须要注意的潜在问题是,假设不论什么资源被ExtractZip写入,而且

1.同一时候在主线程里的一个函数写入

2.或者在主线程被读取,仅仅有在ExtracrZip完毕后才是线程安全的.

In this particular case, my worry would be that if you don't check that you're not trying to download the same file to the same location twice, you could have two threads simultaneously running ExtractZip that interfere with one another.

特别情况是,我操心假设你不去检測你不会试图下载同一个文件到同一个位置两次,你能够有两个线程并行执行在ExtractZip.

unity3D中协程和线程混合的更多相关文章

  1. python中协程实现的本质以及两个封装协程模块greenle、gevent

    协程 协程,又称微线程,纤程.英文名Coroutine. 协程是啥 协程是python个中另外一种实现多任务的方式,只不过比线程更小占用更小执行单元(理解为需要的资源). 为啥说它是一个执行单元,因为 ...

  2. Unity3d之协程自实现测试

    using UnityEngine; using System.Collections; public class TestStartCoroutine : MonoBehaviour { IEnum ...

  3. day37协程与线程套接字通讯

    协程与线程套接字通讯基于多线程实现套接字服务端支持并发,服务端 from socket import * from threading import Thread def comunicate(con ...

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

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

  5. Unity3D之协程(Coroutines & Yield )

    在Unity中StartCoroutine/yield return这个模式到底是怎么应用的? 比如你要一个方法进行一个比较耗时的复杂运算~同时又想让脚本流畅的进行其他操作而不是卡在那里等该方法执行完 ...

  6. python中协程

    在引出协成概念之前先说说python的进程和线程. 进程: 进程是正在执行程序实例.执行程序的过程中,内核会讲程序代码载入虚拟内存,为程序变量分配空间,建立 bookkeeping 数据结构,来记录与 ...

  7. paip.提升性能---协程“微线程”的使用.

    paip.提升性能---协程的使用. 近乎无限并发的"微线程" 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:h ...

  8. Unity 协程与线程

    协程是不同步的 协程 不是 线程,协同程序是 不同步 的 一个线程在程序中和其他线程是异步运行的,在多处理器机器中一个线程可以同时与所有其他线程的实时运行其代码,这使得线程编程能够解决很复杂的事情,因 ...

  9. 深入理解Python中协程的应用机制: 使用纯Python来实现一个操作系统吧!!

    本文参考:http://www.dabeaz.com/coroutines/   作者:David Beazley 缘起: 本人最近在学习python的协程.偶然发现了David Beazley的co ...

随机推荐

  1. Innodb 锁系列2 事务锁

    上一篇介绍了Innodb的同步机制锁:Innodb锁系列1 这一篇介绍一下Innodb的事务锁,只所以称为事务锁,是因为Innodb为实现事务的ACID特性,而添加的表锁或者行级锁. 这一部分分两篇来 ...

  2. 函数flst_add_last

    /********************************************************************//** Adds a node as the last no ...

  3. jQuery 属性操作 - val() 方法

    val() 方法返回或设置被选元素的值. 元素的值是通过 value 属性设置的.该方法大多用于 input 元素. 如果该方法未设置参数,则返回被选元素的当前值. <html> < ...

  4. CF 560e Gerald and Giant Chess

    题意:在h×w的棋盘中从左上角走到右下角,只能向右或向下走,有n个点不可以经过,一共有多少种方案. 解法:dp.先对点按横坐标排序(横坐标相等按纵坐标,也可以反过来)dp[i]表示不经过其他非法点走到 ...

  5. NGINX(三)HASH表

    前言 nginx的hash表有几种不同的种类, 不过都是以ngx_hash_t为基础的, ngx_hash_t是最普通的hash表, 冲突采用的是链地址法, 不过这里冲突的元素不是一个链表, 而是一个 ...

  6. Windows版词汇小助手V3.0发布了

    欢迎使用词汇小助手 作者:IT小小龙 电子邮箱:long_python@126.com 个人博客:http://blog.sina.com.cn/buduanqs 一款跨平台词汇查询记忆学习软件. 已 ...

  7. Algorithm: quick sort implemented in python 算法导论 快速排序

    import random def partition(A, lo, hi): pivot_index = random.randint(lo, hi) pivot = A[pivot_index] ...

  8. ASIHTTPRequest 编码问题

    今天在模拟登陆时,中文的用户名一直登陆不上,对用户名进行了各种转码还是不能解决. 在这个问题上一直卡了半个多小时,最终才发现根本不是用户名的编码问题,而是使用的第三方网络插件的ASIHTTPReque ...

  9. Extjs4 页数重置

    重新加载数据store.loadPage(1);就是到第一页了

  10. 【转载】gcc和g++的区别

    [说明]本文转载自 静心 的文章 http://blog.163.com/lu_jun520/blog/static/5699613420116205148239/ 一般linux系统都自带了gcc编 ...