如何快速返回主线程中执行一个方法

之前在Unity项目中,使用了Loom作为返回主线程的一种工具。

Loom的原理其实很巧妙,就是利用Unity的Update方法来执行需要在主线程中调用的委托。

为什么需要在Update里操作呢,是因为Update是由Unity的主线程Call起的,因此在Update内执行的委托也一定是在主线程中运行,只不过运行前需要Lock一下_queue来防止其他线程访问。

但是因为在Update中执行,当运行Loom的RunOnMainThread方法时,其实依然有一定的延迟(虽然可以忽略不计),那么有没有更直接的办法呢?

之前在其他博客上看到了SynchronizationContext,也就是线程上下文,它可以允许往指定的线程中插入一个方法,使其立刻在指定线程中执行。

那么如果指定的线程为主线程,是不是就可以直接在主线程中插入一个方法来执行了呢?既然有了思路,那么就可以动手了。首先命名下这个工具,暂时叫做MainThreadManager,我们要确保获取的线程上下文一定是主线程的,一般是Unity内的核心管理器创建时,就可以对这个MainThreadManager进行初始化,使其获得主线程上下文。

public class MainThreadManager
{
    // 单例模式
    public static MainThreadManager Instance
    {
        get
        {
            return _instance;
        }
    }

    private static MainThreadManager _instance;

    static MainThreadManager()
    {
        _instance = new MainThreadManager();
    }

    // 指定线程的上下文,目前用于主线程
    private SynchronizationContext m_mainThreadContext = null;

    // 初始化这个管理器,使其获得当前线程的上下文
    public void Init()
    {
        m_mainThreadContext = SynchronizationContext.Current;
    }

    // 在主线程中插入一个方法
    public void RunOnMainThread(Action runOnMain)
    {
        m_mainThreadContext.Send(new SendOrPostCallback((needless)=>
        {
            runOnMain?.Invoke();
        }), null);
    }
}

至此,雏形也就完成了。那么我们可以来实践一下。

如何快速返回主线程中执行一个方法_第1张图片

这是个测试的脚本,如果我们直接在子线程中修改Image的sprite,则必定抛出异常,

那么使用这个管理器来执行的话,也就是注释的部分来进行主线程切换,就正常地替换了Image的sprite了。

这只是一个思路,可以根据这个工具进行更多的扩展,来达到更多的效果。目前就是把学习到的技巧先总结一下,以后再更深入地了解学习。

===========Warning=============

最近发现循环访问这个方法会带来一定的性能问题,因此可能需要再深入研究一下。

你可能感兴趣的:(发现并解决了的错误)