How to quickly return to the main thread to execute a method

Previously in the Unity project, Loom was used as a tool to return to the main thread.

The principle of Loom is actually very clever, which is to use Unity's Update method to execute the delegate that needs to be called in the main thread.

Why do you need to operate in Update? Because Update is started by Unity's main thread Call, so the commission executed in Update must also run in the main thread, but you need to lock the _queue before running to prevent other threads. access.

But because it is executed in Update, when running Loom's RunOnMainThread method, there is still a certain delay (although it can be ignored), so is there a more direct way?

I saw SynchronizationContext on other blogs before, that is, thread context, which allows a method to be inserted into a specified thread to execute it immediately in the specified thread.

So if the specified thread is the main thread, can a method be directly inserted into the main thread to execute? Now that you have an idea, you can do it. First name this tool, temporarily called MainThreadManager. We need to ensure that the obtained thread context must be the main thread. Generally, when the core manager in Unity is created, the MainThreadManager can be initialized to obtain the main thread context.

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

At this point, the prototype is complete. Then we can practice it.

This is a test script. If we directly modify the sprite of the Image in the child thread, an exception must be thrown.

Then, if you use this manager to execute, that is, the commented part to switch the main thread, the sprite of the Image will be replaced normally.

This is just an idea, and more expansions can be made based on this tool to achieve more effects. At present, it is to summarize the skills learned first, and then learn more about learning later.

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

Recently, it has been found that this method of iterative access will bring certain performance problems, so it may be necessary to study it further.

Guess you like

Origin blog.csdn.net/DoyoFish/article/details/106123689