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

之前在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);
    }
}

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

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

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值