Why do Addressable File Operations Work Like This?

I have some questions about the way Unity handles File Open/Read/Write/Close operations when using Addressables. It should be noted that I am on Unity 6000.0.24 and testing on an iPad.

My code is a little complicated, but effectively I am using the method Addressables.LoadAssetAsync. I chain multiple calls together in a single frame, then yield so that other stuff can execute while waiting on the Addressable System to load those assets. All assets that are chain loaded together like this have some common dependencies which are stored in a separate bundle.

My first question is, why does the system need to open, read, and close the same file twice before initiating the actual load of the asset (and it’s dependencies)? As far as I can tell there are no other operations occurring between the separate File.Open/Close calls on any threads.

You can see the two Open calls in this image (and although you cannot see it, yes they are for the same file). The second set of operations is much shorter and not really a huge deal; this is just a curiosity I have, and wanted to make sure it’s not a bug.

My second question is a bigger issue and relates to waiting that is occurring on each working thread (including the main thread) as each thread waits for another file to finish being processed on a separate thread. Here is a high level view of how that looks:

The marked (1-5) profiler markers near the top are my calls to Addressables.LoadAssetAsync. As you can see, the first two execute in sequence, however when the third call is triggered, it ends up needing to wait on some File Operations that have been started on background threads (these file operations are on the files from the first two LoadAssetAsync calls as far as I can tell, which were initially opened/read on the main thread).

I have highlighted the File.Open call that triggers after the Semaphore.WaitForSignal because I want to note that the file it opens here is not involved in any of the file operations from the background threads. For that reason, I don’t really understand why it needs to wait for the threaded file operations to complete before opening this file.

I get that there is interplay between these different loaded assets in the form of dependencies, however I do not know if this adequately explains this issue.

Obviously this is a big deal because this waiting is just delaying the completion of the frame. The only way I can currently see getting around this is by only triggering a single Addressables.LoadAssetAsync call, waiting for it to complete, then triggering the next. It seems like this is not optimal, however, and it would be better to chain up these commands and then let the background threads go to work.

At the moment, that doesn’t seem possible since the call to LoadAssetAsync itself has overhead and needs to wait for other operations to complete before it finishes executing. This is sort of counter intuitive, as one would assume most of the loading process is indeed asyncronous (even though yes, I know that the final integration step of the loading process has to be performed on the main thread and is a heavy operation).

I’m not sure why Unity doesn’t just queue up all of the file operations on background threads, so that the actual calls to LoadAssetAsync are virtually cost free?