【求助】关于协同函数Coroutine能使大量计算的程序不会假死
unity3d吧
全部回复
仅看楼主
level 6
IEnumerator XXX(){
代码块XXX....
yield return new WaitForSeconds(1);
}
这样可以延时一秒我知道。
但是让一个有大量运算的方法在计算时不会使程序假死是如何实现的?
另外如果yield return 下面没有代码 这个yield return 在返回真 之后是不是整个协同就停止了?
我写了一个象棋程序,在5层的时候因为上百次的计算,直接使程序假死了。。。。
只知道使用协同能处理,但是不知道具体该怎么做。自己试着写了好多种方式都失败了
假设下面这个循环会卡死 于是我把它放在了协同函数里面
我要在哪里返回yield return 返回个什么值 然后在哪里调用它 才能使整个for跑完 并且不会卡顿
IEnumerator XXX(){
for(int i=0;i<100000;i++)
for(int j=0;j<100000;j++){
}
}
2016年06月02日 01点06分 1
level 6
自己顶
2016年06月02日 02点06分 2
level 1
协程的C++实现,用反编译工具看协程编译后的代码应该就知道协程是怎么工作的了:
Coroutine::Coroutine()
{
mCoroutine = NULL;
mMoveNext = NULL;
mGetCurrent = NULL;
begin = 0;
wait = 0;
}
Coroutine::~Coroutine()
{
}
bool Coroutine::Init(MonoObject* pCoroutine)
{
MonoClass* mono_class = mono_object_get_class(pCoroutine);
if (mono_class)
{
mMoveNext = mono_class_get_method_from_name(mono_class,"MoveNext",0);
mGetCurrent = mono_class_get_method_from_name(mono_class,"System.Collections.IEnumerator.get_Current",0);
if (mMoveNext&&mGetCurrent)
{
mHandle = mono_gchandle_new(pCoroutine,true);
mCoroutine = pCoroutine;
return true;
}
}
return false;
}
void Coroutine::Clean()
{
}
void Coroutine::Run()
{
//1条件测试
if(DATA_PROVIDER->m_curTime - begin <wait) return;
//2 run
void* params[1] = {0};
MonoObject* exc = NULL;
MonoObject* ret = NULL;
ret = mono_runtime_invoke( mMoveNext, mCoroutine, params , &exc );
#ifdef WIN32
if ( exc!=NULL )
{
string error = App::Utility_ExceptionToString( exc );
LogManager::getSingleton().logMessage(error);
}
#endif
//测试返回值
if (ret)
{
bool result = *(bool*)((char *)ret +8);//4字节对齐
if (!result)
{
setExpire();
}
else
{
exc = NULL;
ret = NULL;
ret = mono_runtime_invoke( mGetCurrent, mCoroutine, params , &exc );
#ifdef WIN32
if ( exc!=NULL )
{
string error = App::Utility_ExceptionToString( exc );
LogManager::getSingleton().logMessage(error);
}
#endif
MonoObject* current = ret;
if (current)
{
MonoClass* mono_class = mono_object_get_class(current);
if (mono_class)
{
const char* klassName = mono_class_get_name(mono_class);
if(strcmp(klassName,"WaitForSeconds")==0)
{
wait = *(float*)((char *)current +8);//fixme???
begin = DATA_PROVIDER->m_curTime;
}
else
{
LogManager::getSingleton().logMessage("not implemented");
}
}
}
}
}
}
2016年06月02日 02点06分 3
level 7
在你的例子的話:
IEnumerator XXX(){
for(int i=0;i<100000;i++)
for(int j=0;j<100000;j++){
}
yield return null;
}

Enumerator XXX(){
for(int i=0;i<100000;i++)
for(int j=0;j<100000;j++){
yield return null;
}
yield return null;
}
用WaitForSecond會很慢
2016年06月02日 02点06分 4
我在尝试这样写了 ,for循环里面有递归调用,然后他就只是给我执行了大概一轮的样子吧。递归里面的他就不管了[泪]
2016年06月02日 06点06分
我写了象棋程序 ,算法哪里百万次的计算导致程序假死了 不知道怎么用协同处理他
2016年06月02日 06点06分
@魂太刀 线程出现这样一个问题,子线程里面的算出来的值在主线程里面没有得到[泪]。新手不懂这些东西,太蛋疼了
2016年06月02日 06点06分
我也不太清楚...加油...
2016年06月02日 07点06分
level 5
可以分帧计算吧
2016年06月02日 06点06分 5
1