我看过一些关于使用协程在主线程上运行函数的文章,例如Thread Ninja:
IEnumerator StartExamples()
{
//Jump to main thread
yield return Ninja.JumpToUnity;
Destroy(someGameObject); //OK
//Jump back to background thread
yield return Ninja.JumpBack;
}
它对我的代码不起作用,因为我想从套接字侦听器跳转到主线程。
SocketIOClient.Client socket;
IEnumerator StartExamples()
{
socket.On("connect", (fn) =>
{
WriteLine("\r\nConnected event...\r\n");
//Jump to main thread
yield return Ninja.JumpToUnity; //ERROR: couldn't do a yield return
Destroy(someGameObject);
//Jump back to background thread
yield return Ninja.JumpBack; //ERROR: couldn't do a yield return
});
}
那么我们有什么解决方法吗?我希望我能像这样跳转到主线程:
Dispatcher.BeginInvoke(() =>
{
//Unity API
Destroy(gameObject);
});
根据我的评论,使用 uPromise;
class Example
{
private Promise BeginSocketConnection()
{
Deferred retPromise = new Deferred();
socket.On("connect", (fn) =>
{
// We're no longer on the main thread ):
// But we can resolve our promise!
retPromise.Resolve();
});
return retPromise;
}
private void SocketConnectedSuccessfully()
{
// Executing on main thread
}
private void Start()
{
// We start in the main thread
BeginSocketConnection().Done(x =>
{
SocketConnectedSuccessfully();
});
}
}
这不允许您在同一代码块内的线程之间跳转,但是通过使用回调系统,您可以提醒主线程执行操作,而不会到处启动和产生混乱的协程。更易于查看和维护。
如果你不想使用扩展,比如其他评论中提到的 uPromise 和 Unity Thread Helper,并且不想使用 MonoBehavior 的协程,你也可以使用 SynchronizationContext:
// On main thread, during initialization:
var syncContext = System.Threading.SynchronizationContext.Current;
// On socket listener thread
syncContext.Post(_ =>
{
// This code here will run on the main thread
Destroy(gameObject);
}, null);
Dispatcher.Enqueue(() =>
{
//Unity API
Destroy(gameObject);
});