Hi, I am new to Unity. In my game there are tons of assets that need to be created/rendered on the fly, via calls to a separate application. The application is extremely resource-intensive, hence we cannot make more than 1 simultaneous call at a time. Also, we need the ability to prioritize certain requests above others because the user might request an asset or come near certain assets.
At first I tried using the await/async pattern. Each object has its own await/async so they can easily put the result into the image or text asset. Low-priority objects need to acquire a low-priority lock before acquiring the resource lock; high-priority objects only need the resource lock. However, I realized it might become complicated if I ever need more control over all these requests (e.g. cancel some of them or move them around in the queue), and it seemed like the real proper way to implement this is a queue-based system where I just have 1 giant queue and each object can add their actions to it. A constantly running background task will execute the queue tasks one after another as long as the queue still has actions to run.
Now it is mostly working, but it seems like my background thread has a bunch of limitations in Unity. I make the background thread inside one of my Start() functions by doing a Task.run(() { while (true) { [do stuff] } });
The main limitation is, there is no way to “sleep” the thread when checking if the queue has any items. Invoke with delay doesn’t work (function doesn’t get called), and Coroutine with yield doesn’t work from inside a Task. Without any way to sleep and give it a break, it will constantly be checking if actionQueue.Count > 0 in the while(true) loop which I’m afraid isn’t optimal for the CPU in the situation where no actions are currently in the queue.
I considered a Coroutine that’s not wrapped by a Task, but then it will need to start a Task when running the queue’s action; then, it can neither await the Task (because the main thread will block), nor can it refrain from awaiting (because then more than 1 will be executed simultaneously).