Am I missing something with Threading.Tasks?

I’m trying to do an async block of code inside an async method with this:

{
//Debug prints
await Task.Delay( 4000);
//Debug prints
//Code
//Debug prints
});

It prints correctly the first debug line, and after waiting that time, it prints the second one. However, if I try to use any “unity function” related to gameobjects like instantiating a new gameobject on scene or trying to access an already existing one, it stops. It doesn’t throw any exception, it simply stops printing debugs and of course any of the gameobject operations have been done.

Any idea? Feels like I shouldn’t be using tasks to manage gameplay related code. Should I come back to coroutines?

Yes, don’t use async / threading when you need to call Unity functions. That’s it.

2 Likes

Well, it does throw an exception, however exceptions raised in threadpool threads are usually not catched by Unity as those threads are completely seperated from the engine.

You can not use most of the Unity API from other threads. They can only be used on the main thread.

1 Like

if you want to use async await with Unity methods you need to be sure you do not leave main thread.
if you need to use something like Task.Run you could replace it with

Task.Factory.StartNew(async () =>
{
}, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.FromCurrentSynchronizationContext() );

The point here is to use TaskScheduler created from unity SynchronizationContext witch will make await continue on main thread.
But you need to be careful with StartNew. it more complicated than Task.Run.

1 Like

Thanks for your answer. I have to say this behaviour is a little bit underwhelming and counterintuitive, because this works just fine.

public async override void OnStateEnter() { 
await Task.Delay( 4000);
GameObject g = GameObject.Instantiate(Resources.Load<GameObject>("whatever")); 
}

I suppose I will avoid using Tasks from now on with Unity because they are doing me more harm than good haha.

It not catches by unity not becouse it thrown in another thread but becouse Task catch it. it could b accessed though Exception property of task instance returned by Task.Run