当我从websockets获得一些数据并试图通过协同机制显示数据时,我遇到了一些小麻烦。
首先,我将一个classA附加到一个打开websocket并显示接收到的数据的对象上:
public class ClassA : MonoBehaviour {
...
public IEnumerator ConnectWebSocket(url)
{
// in the websocket class, start the websocket connection, which
// will return data through a callback inside the return string
WebSocketClass.WebSocketStart(url, delegate(string result)
{
// receive websocket data and call the functions that displays it
WebSocketData(result);
});
// wait for the socket connection
while (WebSocketClass.WebSocketGetState() == WebSocketSharp.WebSocketState.CONNECTING)
{
yield return 0;
}
if (WebSocketClass.WebSocketGetState() == WebSocketSharp.WebSocketState.OPEN)
{
break;
}
...
}
// function that gets websocket data and starts couroutine to display it
public void WebSocketData(string data)
{
StartCoroutine(DisplayMessage(data));
}
}但是联合抱怨下一个错误:
只能从主线程调用StartCoroutine_Auto。在加载场景时,将从加载线程执行构造函数和字段初始化程序。不要在构造函数或字段初始化器中使用此函数,而是将初始化代码移动到“唤醒”或“启动”函数。
我在团结论坛上搜索并找到了这样的解决方案:
public class ClassA : MonoBehaviour {
...
public IEnumerator ConnectWebSocket(url)
{
// in the websocket class, start the websocket connection, which
// will return data through a callback inside the return string
WebSocketClass.WebSocketStart(url, delegate(string result)
{
// receive websocket data and call the functions that displays it
WebSocketData(result);
});
// wait for the socket connection
while (WebSocketClass.WebSocketGetState() == WebSocketSharp.WebSocketState.CONNECTING)
{
yield return 0;
}
if (WebSocketClass.WebSocketGetState() == WebSocketSharp.WebSocketState.OPEN)
{
break;
}
...
}
// function that gets websocket data and starts couroutine to display it
public void WebSocketData(string data)
{
DoOnMainThread.ExecuteOnMainThread.Enqueue(() => { StartCoroutine(DisplayMessage(data)); });
}
}
// class to manage the websocket data display inside the main thread
public class DoOnMainThread : MonoBehaviour
{
public readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();
public virtual void Update()
{
// dispatch stuff on main thread
while (ExecuteOnMainThread.Count > 0)
{
ExecuteOnMainThread.Dequeue().Invoke();
}
}
}而且起作用了!问题是,即使我在同一个cs文件中编写了这两个类并附加到一个对象,但当我更改场景时,返回到该场景,并从websocket接收任何数据,下一个错误将显示:
MissingReferenceException:类型'ClassA‘的对象已被销毁,但您仍在尝试访问它。您的脚本应该检查它是否为null,或者不应该销毁该对象。C:/BuildAgent/work/d63dfc6385190b60/artifacts/EditorGenerated/UnityEngineMonoBehaviour.cs:62) ( UnityEngine.MonoBehaviour.StartCoroutine ) (IEnumerator例程)
在加载新场景时,我试图不销毁该对象,如文档所述:
void Awake()
{
DontDestroyOnLoad(transform.gameObject);
}但错误仍然出现。
奇怪的是,虽然有一个错误,从websocket接收到的数据显示没有任何问题。
有人知道如何避免这个问题吗?有没有办法在不使用第二个类的情况下触发主线程内的协同线?或其他避免此错误的解决方案?
谢谢!
发布于 2014-10-21 09:08:09
我发现了问题:
public readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();它是静态的,所以当一个公共类被实例化并生成另一个ExecuteOnMainThread时,它就成了一个问题。
因此,只要删除“静态”,并使其破坏和生成自己,每次ClassA是由统一。
现在它就像一种魅力:)
https://stackoverflow.com/questions/26481929
复制相似问题