(C#) Question on Await and Void Functions

Godot Version

v4.2.2

Question

Hello all.

Like it says in the title, I am wondering if you can use await to wait on a function that returns void, in this case another _Ready() function.
For more context, I am following a gdscript tutorial while translating the code to C#. I reached a part where the person in the tutorial uses await owner.ready in one node so that the rest of the nodes in the scene to ready before it itself readies.
In C#, I know it would translate to this:

	public async override void _Ready(){
		await Owner._Ready();
		// rest of the code here
	}

Unfortunately, that returns the following error when I try to build:

CS4008: Cannot await ‘void’

After researching how C# uses await, I feel stuck as the best I could find was that the function being waited on has to return something.
If anyone has tried this same idea and found a way around it, such as using something other than await, I would gladly appreciate the help.

Many thanks in advanced!

Gerardo

I am familiar with C#, but have never used it with Godot. However, I think your problem is you are waiting for the wrong function. The _ready() function is a private virtual function you can use to update your node as it’s being created. The ready() function is actually what is called when the node is actually ready. So my first though is try:

	public async override void _Ready(){
		await Owner.Ready();
		// rest of the code here
	}

Another thing you can do is attach the ready signal from the parent in your _ready() function, and put the code into another function. (Again, not having used Godot with C#, this is a best guess.)

public override void _Ready()
{
    var owner = Owner;
    owner.Ready += OnParentReady;
}

private void OnParentReady()
{
	// rest of the code here
}

You can also read more about signals.

I would prefer the second method to the first. Await is necessary sometimes, but if at all possible it is preferred in Godot to avoid waits of any kind. I realize you are following a tutorial, just thought it was worth mentioning.

1 Like

Thank you for the reply, dragonforge-dev. I tried both just to see how Godot handles them; while the former gave me the following error:

CS0079: The event ‘Node.Ready’ can only appear on the left hand side of += or -=

The latter, however, was built without issue and works just as it shows in the tutorial. I will definitely give the signals doc another read to ensure I understand it better.

Thank you so much for your help!

1 Like

await Owner._Ready();
with this you gonna call Ready one extra time?

I think you want use this:

	public override async  void _Ready()
	{
		await ToSignal(GetParent(), SignalName.Ready);
		GD.Print("ChildReady");
	}

obraz

1 Like

Hi @gerardo098,

Yes, C# works a little different from GDScript, because GDScript uses a concept called coroutine with await (which is not available in C# language by definition) :slight_smile:

“Coroutines are computer program components that allow execution to be suspended and resumed, generalizing subroutines for cooperative multitasking.”

In GDScript you can learn more about it here.

We can achieve a “similar” coroutine result using async/await and event as mentioned by @dragonforge-dev and @Moreus .

Just a little clarification about async/await: in C# when using the async keyword, the most common and recommended return types are Task (equivalent to returning void in synchronous methods) and Task<T> (when you want to return a value in the T template). Using async void methods is possible, but is not a good approach because they are harder to catch/handle compared to Task and Task<T>.

I just created an example so you can see it in action. :slight_smile:

Repo:

3 Likes

@vrravalos That was very interesting. I learned something new!

1 Like

Thank you for the example code, Vrravalos! I am giving it a look and it is very helpful.
And thank you to everyone else as well! I’ve learned a lot about asycn types and signals with your help :pray:

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.