在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