如何在不使用 Unity 协程的情况下在主线程上执行 运行 函数
How to run functions on main thread without using Coroutine in Unity
我看过一些关于在主线程上使用协程 运行 函数的文章,例如 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();
});
}
}
这不允许您在同一个代码块内的线程之间跳转,但通过使用回调系统,您可以提醒主线程执行一个操作,而无需启动杂乱的协程并在各处产生。更易于查看和维护。
我最终使用了一个非常有用的扩展,叫做 Unity Thread Helper。它是免费的,足以满足我的需要!
这是用法:
UnityThreadHelper.Dispatcher.Dispatch(() =>
{
Destroy(a);
});
注意:Dispatcher 是一个单例对象,它将在您第一次调用时被初始化。您必须在主线程上进行第一次调用,因为它使用了一些 Unity API.
private void Start()
{
var ugly = UnityThreadHelper.Dispatcher;
}
希望对您有所帮助!
如果你不想使用其他评论中提到的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);
我看过一些关于在主线程上使用协程 运行 函数的文章,例如 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();
});
}
}
这不允许您在同一个代码块内的线程之间跳转,但通过使用回调系统,您可以提醒主线程执行一个操作,而无需启动杂乱的协程并在各处产生。更易于查看和维护。
我最终使用了一个非常有用的扩展,叫做 Unity Thread Helper。它是免费的,足以满足我的需要!
这是用法:
UnityThreadHelper.Dispatcher.Dispatch(() =>
{
Destroy(a);
});
注意:Dispatcher 是一个单例对象,它将在您第一次调用时被初始化。您必须在主线程上进行第一次调用,因为它使用了一些 Unity API.
private void Start()
{
var ugly = UnityThreadHelper.Dispatcher;
}
希望对您有所帮助!
如果你不想使用其他评论中提到的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);