博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unityclient通信測试问题处理(一)
阅读量:7083 次
发布时间:2019-06-28

本文共 1659 字,大约阅读时间需要 5 分钟。

Unityclient通信測试问题处理(一)

        近期在測试程序的通信模块时。遇到了一个问题:Unity的API函数仅仅能在主线程中调用。而作为client程序,我单独启用了一个监听线程来接收服务端发送的消息,消息接收后的解析函数也由该线程一并调用。那么问题来了。在解析函数之中,我将不能调用Unity的不论什么API函数。

           之前由于没有意识到这个问题。很多处理都是直接放在消息解析函数中做的,程序一经測试首先就报出了下面错误:     

          

           CompareBaseObjectsInternalcan only be called from the main thread…

           看到这条信息,自己寻思是怎么回事,像是对象的比較推断上出了问题,于是開始查看代码。

后来发现是由于在解析函数中。收到消息后调用了一个管理者类中的方法。这个管理者类使用单例模式实现,而且继承了MonoBehaviour类。在获取单例对象时,涉及了对象的判空操作。代码例如以下所看到的:

 

           if ( null ==_uniqueInstance ){...}

    

           正是这个Operate == 的调用。引发了这个错误。由于管理者类继承了MonoBehaviour类。而MonoBehaviour类重写了Operate ==。所以在获取单例对象时,调用的是Unity自己的实现。而这时的代码运行逻辑位于监听线程之中,并不是Unity3D 的主线程,于是就报出了这个CompareBaseObjectsInternalcan only be called from the main thread的错误信息。那么该怎么解决问题呢?自己到网上搜索了一下。找到了网友提供的一个方法。就是用.Net中的Object.ReferenceEquals函数来进行对象的推断操作,替换掉Operate ==的方式。

经过測试,这样的方法确实可行。

在查看ReferenceEquals函数的文档后得知,由于ReferenceEquals函数是不能被重写的。所以不会由于这是Unity自己实现的版本号,而限定了仅仅能在主线程中调用。所以问题得以解决。另外还要注意的一点是,使用ReferenceEquals函数比較两个对象是否同样,当这两个对象为值类型时。会运行装箱操作,要注意一下。

           以下是自己改动后的获取单例的方法:

    public static SceneMng GetInstance()

    {

        if (ReferenceEquals( null, _uniqueInstance ) ) {

            lock (_lock ) {

                if (ReferenceEquals( null, _uniqueInstance ) ) {

                    //_uniqueInstance= ( SceneMng )GameObject.FindObjectOfType(

                    // typeof( SceneMng ) );

               }

           }

       }

        return _uniqueInstance;

   }

 

           攻克了这个错误,随之而来的是自己的实例无法初始化的问题,由于被凝视掉的函数是不能在此调用的(监听线程)。

解决的办法也好说。直接在Awake函数中进行单例的初始化:

 

    void Awake( )

    {

        //singleton initialize

       _uniqueInstance = this;

    }

 

           场景载入,Awake函数运行时。单例对象就初始化完毕了。OK,能够投入使用了。也不用操心线程的问题了。

           在測试过程中。另一些地方的处理也由于受到了这个主线程的限制。而做出了一些改动,待自己整理过后,再继续写上来。有不正之处欢迎大家指出,一起交流讨论。

     本文出自杜晓萌的博客。未经特殊表明皆为本人原创,请勿用于不论什么商业用途,转载请保持完整性并标明出处:http://blog.csdn.net/haohan_meng

转载于:https://www.cnblogs.com/gavanwanggw/p/6946925.html

你可能感兴趣的文章
ProtecTIER网关演绎重复数据删除的硬道理
查看>>
Android 播放Gif 动画
查看>>
(原创)创建windows域---深入理解域概念
查看>>
虚幻4,BP写了一个简单的三线跑酷工程
查看>>
“10亿元身价”CEO的6个密码
查看>>
C++/CLI思辨录之内部指针的两面性
查看>>
【英语天天读】I want I do I get
查看>>
DIV层+CSS实现锁屏
查看>>
浅谈C/C++中的顺序点和副作用
查看>>
每周一书-《做自己-鬼脚七自媒体第一季》
查看>>
如何删除JAVA集合中的元素
查看>>
jQuery 事件 - trigger() 方法
查看>>
模态窗口被IE 7给糟蹋得不成样子了
查看>>
你不知道的Spring配置文件
查看>>
Spark源码分析之Spark-submit和Spark-class
查看>>
SOA系列之基本特性
查看>>
js中的"=="和equals()以及is()三者的区别
查看>>
谨慎注意WebBrowser控件的DocumentCompleted事件
查看>>
回头再说 005 --温暖的文字和音乐
查看>>
C#进行Visio二次开发之电气线路停电分析逻辑
查看>>