通过Unity中的后台线程调用主线程中的函数
Invoking a function in main thread via background thread in Unity
我正在使用以下代码在后台从服务器检索数据。
new Thread(retrieveData()).Start();
以下是从服务器接收数据的函数,
void retrieveData()
{
while (true)
{
string data = subSocket.ReceiveFrameString();
}
}
我想根据从服务器接收到的数据创建一个预制件。不幸的是,我无法从使用 retrieveData
的后台线程执行此操作。如何向主线程发送回调并在指定位置创建预制件?
大概有多种方式。
最常用的是所谓的“Main Thread Dispatcher”模式,它可能类似于
// An object used to LOCK for thread safe accesses
private readonly object _lock = new object();
// Here we will add actions from the background thread
// that will be "delayed" until the next Update call => Unity main thread
private readonly Queue<Action> _mainThreadActions = new Queue<Action>();
private void Update ()
{
// Lock for thread safe access
lock(_lock)
{
// Run all queued actions in order and remove them from the queue
while(_mainThreadActions.Count > 0)
{
var action = _mainThreadActions.Dequeue();
action?.Invoke();
}
}
}
void retrieveData()
{
while (true)
{
var data = subSocket.ReceiveFrameString();
// Any additional parsing etc that can still be done on the background thread
// Lock for thread safe access
lock(_lock)
{
// Add an action that requires the main thread
_mainThreadActions.Enqueue(() =>
{
// Something that needs to be done on the main thread e.g.
var text = new GameObject("Info").AddComponent<Text>();
text.text = Data;
}
}
}
}
我正在使用以下代码在后台从服务器检索数据。
new Thread(retrieveData()).Start();
以下是从服务器接收数据的函数,
void retrieveData()
{
while (true)
{
string data = subSocket.ReceiveFrameString();
}
}
我想根据从服务器接收到的数据创建一个预制件。不幸的是,我无法从使用 retrieveData
的后台线程执行此操作。如何向主线程发送回调并在指定位置创建预制件?
大概有多种方式。
最常用的是所谓的“Main Thread Dispatcher”模式,它可能类似于
// An object used to LOCK for thread safe accesses
private readonly object _lock = new object();
// Here we will add actions from the background thread
// that will be "delayed" until the next Update call => Unity main thread
private readonly Queue<Action> _mainThreadActions = new Queue<Action>();
private void Update ()
{
// Lock for thread safe access
lock(_lock)
{
// Run all queued actions in order and remove them from the queue
while(_mainThreadActions.Count > 0)
{
var action = _mainThreadActions.Dequeue();
action?.Invoke();
}
}
}
void retrieveData()
{
while (true)
{
var data = subSocket.ReceiveFrameString();
// Any additional parsing etc that can still be done on the background thread
// Lock for thread safe access
lock(_lock)
{
// Add an action that requires the main thread
_mainThreadActions.Enqueue(() =>
{
// Something that needs to be done on the main thread e.g.
var text = new GameObject("Info").AddComponent<Text>();
text.text = Data;
}
}
}
}