客户端接受数据包的队列如下:
测试可以得到明显的溢出结果,肯定是有问题的!
在catch中输出具体异常:Object reference not set to an instance of an object!
然后通过debug.log定位具体异常位置!这也不算浪费时间,但确实拖了大概有2周的时间。
问题出在3号位置和4号位置之间
也就是onMessage中有错!之前能继续执行说明是被try给救了。
错误的时间和位置都找到了,model没有解码出来!只要能解决问题,我咋都行!
测了一下,只要能进来,都是49次,相同的message的总和也是49次!
问题又回到了List[0]那里:
继续测试,找list[0]里面到底存的什么!只要onMessage读不出来,RemoveAt也一直不会动的,自然就卡死了,队列死锁。
这时需要学会一个新的调试方法!在catch中下断点!没错!这样可以既不影响程序正常运行,又可查看异常时的状态!尤其是堆栈!
确实是出现list[0]=null,list[1]还是124包的情况了!
我尝试了寻找原因,发现并不现实,但是知道原因,解决起来很简单!
出现异常时,在catch中运行一次removeAt(0)即可!
try
{
Debug.Log("队列错误1");
List<SocketModel> list = NetWorkScript.getInstance().getList();//这么写的目的是实现全局对象,关键是要做到不卡
Debug.Log("队列错误2"); //List<SocketModel> list = instance.getList();
for (int i = 0; i < 8; i++)//每帧8条信息,i不参见内部算法,所以有错一定错在头顶null!
{
if (list.Count > 0)
{
Debug.Log("队列有货!!!!!!!!!!!!!!");
SocketModel model = list[0];//后面有取出信息的
Debug.Log(model.type+" "+DateTime.Now);//
Debug.Log(model.area + " " + DateTime.Now);
Debug.Log(model.command + " " + DateTime.Now);
Debug.Log(model.message + " " + DateTime.Now);
Debug.Log("哪天见,哪天算完");
Debug.Log("队列错误3");
OnMessage(model);//处理当前的第一条信息
Debug.Log("队列错误4");
list.RemoveAt(0);//读了就删,很好的--收发不用一一对应!合理利用堆栈和删除栈顶即可!!!
Debug.Log("队列错误5");
//Debug.Log("成功移动数据包堆栈" + Time.time);
}
else
{
break;//无消息跳出循环
}
}
}
catch (Exception ex)
{
//MyLog.form.textAdd(ex.Message);
Debug.Log("队列有货!!!!!!!!!!!!!!异常");
Debug.Log("出现异常时,在catch中运行一次removeAt(0)即可"+ex.Message+" "+DateTime.Now);
///有错一定错在头顶null
List<SocketModel> list = NetWorkScript.getInstance().getList();
list.RemoveAt(0);
//list.RemoveAt(0);
}
实测结果可以有效防止异常: