繁体   English   中英

如何在主线程上运行函数而不使用 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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM