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.