Running Unity Specific Code on the Main Thread - BeardedManStudios/ForgeNetworkingRemastered GitHub Wiki

We have created a helper class for you to be able to offload any logic to the main thread from a separate thread. This helper class is called MainThreadManager and there are 2 main ways that you can use this class. The entry point for both methods of use is the static method Run ; see the code snippets below for practical uses. The examples below emulate an RPC method's contents.

MainThreadManager.Run Function Pointer

public override void MyCustomRPC(object[] args)
{
	// Register the private function within this class to be called on the main thread
	MainThreadManager.Run(OtherFunction);
}

private void OtherFunction()
{
	Debug.Log("Hello World!");
}

You can see that the above example requires another accessible method in order to pass it into the main thread manager's Run method.

MainThreadManager.Run Lambda Expression

public override void MyCustomRPC(object[] args)
{
	// Setup a temporary method call (lambda expression) to be executed on the main thread
	MainThreadManager.Run(() => { Debug.Log("Hello World!"); });
}

The above is the preferred method

The lambda expression is a native C# feature that allows you to essentially create an inline function at runtime. Please see this website or the official documentation for more information on lambda expressions.

What does the Main Thread Manager do?

The Main Thread Manager is actually a pretty small and simple singleton class. When you send a method pointer or inline expression into the Run method it will be added to a queue. The Main Thread Manager is a Unity GameObject and will automatically create itself if one is not created already. By default every FixedUpdate for this object, it will check to see if there are any pending methods in the queue, if so it will run them and remove them from the queue. By running these methods in the FixedUpdate they are automatically ran on the main thread.

You can specify which Unity update method to run the lambda expression or method on by adding the second parameter.

To run the method/lamdba expression when Unity's Update runs you need to specify UpdateType.Update as the second parameter to MainThreadManager.Run()

public override void MyCustomRPC(object[] args)
{
	// Setup a temporary method call (lambda expression) to be executed on the main thread
	MainThreadManager.Run(() => { Debug.Log("Hello World!"); }, UpdateType.Update);
}

Automatic MainThreadManager.Run() on RPCs

If you have ticked the box UseMainThreadManager in the MultiplayerMenu (script, default in BeardedManStudios and default on the starting MultiplayerMenu Scene), then inside every RPC, the entire function is wrapped

MainThreadManager.Run(() => { your code });

For example, say you have this code:

// This is an RPC function made via the NetworkContractWizard, inside a network object
public void override PrintRPC(RpcArgs args)
{
    Debug.Log("Hello World!");
    Debug.Log("We are inside an RPC!");
}

When you tick/check the UseMainThreadManager checkbox (which is true by default), then Forge will automatically make sure that the RPC will be executed on the Unity main thread without the need for you to wrap your code inside a MainThreadManager.Run() call.

There is no real reason to not use the automatic checkbox, unless you simply don't use Unity (See C# headless server), the MainThreadManager is a Monobehaviour that ensures that code run by it will always execute on the main thread.