简体   繁体   English

如何在主线程上运行函数而不使用 Unity 中的协程

[英]How to run functions on main thread without using Coroutine in Unity

I've come across some articles about using coroutine to run functions on main thread, such as Thread Ninja :我遇到过一些关于使用协程在主线程上运行函数的文章,例如Thread Ninja

 IEnumerator StartExamples()
{
    //Jump to main thread
    yield return Ninja.JumpToUnity; 

    Destroy(someGameObject); //OK

    //Jump back to background thread
    yield return Ninja.JumpBack;  
}

It didn't work on my code since I wanted to jump to main thread from a socket listener.它对我的代码不起作用,因为我想从套接字侦听器跳转到主线程。

 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 
    });
 }

So do we have any workaround for this?那么我们有什么解决方法吗? I wish I could jump to main thread like this:我希望我可以像这样跳转到主线程:

 Dispatcher.BeginInvoke(() =>
{
    //Unity API
    Destroy(gameObject);
});

As per my comment, using uPromise ; 根据我的评论,使用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();
        });
    }
}

This doesn't allow you to jump between threads within the same codeblock, but by using a callback system you can alert the main thread to execute an action without messy coroutines being started and yielded all over the place. 这不允许您在同一代码块内的线程之间跳转,但是通过使用回调系统,您可以提醒主线程执行操作,而无需启动混乱的协程并在各处产生混乱。 Much nicer to look at and maintain. 看起来和维护起来要好得多。

I ended up using a very helpful extension called Unity Thread Helper . 我最终使用了一个非常有用的扩展,称为Unity Thread Helper It's free, and more than enough for my need! 它是免费的,并且足以满足我的需求!

This is the usage: 这是用法:

 UnityThreadHelper.Dispatcher.Dispatch(() =>
        {
            Destroy(a);

        });

NOTICE: Dispatcher is a singleton object, it will be initialized on your first call. 注意:Dispatcher是一个单例对象,它将在您第一次调用时初始化。 You have to do your first call on main thread, because it uses some Unity API. 您必须在主线程上进行首次调用,因为它使用了一些Unity API。

 private void Start()
{
    var ugly = UnityThreadHelper.Dispatcher;
}

Hope this helps! 希望这可以帮助!

If you don't want to use extensions, like uPromise and Unity Thread Helper mentioned in the other comments, and don't want to use MonoBehavior's coroutines, you can also use SynchronizationContext :如果你不想使用扩展,比如其他评论中提到的 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