在unity中我们使用多线程时。用子线程调用主线程时。用到unity的东西时就会报如下的错误。
CompareBaseObjectsInternal can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don’t use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
一个简单的办法就是。当多线程调用时。将内容展示存下来。然后通过主线程的函数去下发。比如Update下发
例:
public void BeginTheTimer() { //建立连接 try { socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socketClient.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9070)); IsConnected = true; } catch (Exception e) { Debug.Log(e); } Thread receiveThread = new Thread(new ThreadStart(socketReceive)); receiveThread.Start(); receiveThread.IsBackground = true; } //数据接收线程添加变量DateTime lastConnect=DateTime.now; //若接收数据为echo,则不作处理,若为其他数据,显示在richTextBox中; public void socketReceive() { while (true) { try { byte[] buff = new byte[1024]; int count = socketClient.Receive(buff); if (count > 0) { string str = Encoding.UTF8.GetString(bytes, 0, i); message(str); } } catch (SocketException) { IsConnected = false; Thread.CurrentThread.Abort(); } } } private void message(string data) { notifierDataList.Add(data); } void Update() { if(notifierDataList.Count > 0) { //如这。我用的是接口下发消息。通过字典来队列消息。每次下发一条。然后将已下发的移除 //就不会出现线程安全问题了 Notifier(999, null, notifierDataList[0]); notifierDataList.RemoveAt(0); } }
转载来源:小宝个人笔记 » Unity线程安全:CompareBaseObjectsInternal can only be called from the main thread