- Home /
www class blocks script execution
Ok, maybe this is a silly question: We are loading some files from disk and use www class for that und my colleague has used WWW class for that, but WITHOUT putting it into a coroutine. Instead he put a simple while Loop behind it, to wait until it ended (so the end is awaited in the current frame, where the loading was started).
public static bool IsValidWWW(WWW www) {
while (!www.isDone)
;
return www != null && string.IsNullOrEmpty(www.error) && www.size > 0;
}
The files are very small, so that doesn't make any problem and everything works fine in Editor, on Android and Standalone, but on iOS the device is blocked.
My Guess is, that www class uses a special amount of time in the frame for downloading, then stops and the next frame is loaded. On the other platforms it extends the time for download, but on iOS the Frame is clamped to 30 so the time es up, but the execution can't go on, because it is trapped in a while loop.
Or is www executed thread based?
I just want to be sure, how it works - because if this is the cause of the error, we have to change A LOT OF code, to make this coroutines based.
Answer by callen · Dec 10, 2015 at 08:45 PM
It's surprising that this works for you as often as it does, (I even tested because I didn't believe it!) but I'm guessing the reason is threading. It is likely the case that the WWW operation can be offloaded to another thread on some platforms, but on iOS it needs to use the main thread, at least to start the operation.
In general however, you should never do this! I tested again in the editor with my internet disconnected, and sure enough the editor froze then crashed, because it was stuck in the loop.
There's a reason why every language's net APIs use Async methods and callbacks, and you will likely have to redesign along this pattern. To 'fix' your method you could write it like this:
public static IEnumerator IsValidWWW(WWW www, Action<bool> callback) {
while (!www.isDone)
yield return null;
callback( www != null && string.IsNullOrEmpty(www.error) && www.size > 0 );
}
There's really no way around it, because there's never a guarantee a net operation can complete within any fixed timeframe. Especially on mobile, where weird stuff can happen in the OS and your WWW might not return for a few seconds.
Edit: i must have misread about loading local data via Www class. While that should work, the fact that you see this behavior makes me think to avoid it. Maybe something about the file:// scheme is operating on ios in a way that requires the frame to conclude before it completes (while other platforms dont)
The .net file io classes should be able to handle any of your needs though. It might be as simple as
if (File.Exists (path)) text = File.ReadAllText(path);
Hmmm we are not loading from Internet with this - I made the Internet Downloads myself correctly with coroutines. $$anonymous$$y friend made that one for reloading it from disk. So it should either finish sometimes or throw an error, that the file doesn't exist. That's what he expected. But he doesn't know anything about coroutines. The interesting Thing is, that the download stops completely, but has started. Progress shows 0.5 but it stucks there, so I still wonder why and why it works on other systems.
Yes, File.io operations was the next thing i was thinking about, but that offers another new problem. I download Image (png) and audio (mp3) files from the Internet (with www class inside a coroutine - everything fine), store it on the device und want to display or play it later in the game. i can read them as bytes with file.io and i can put images with loadImage into a texture to work with it, but i haven't found a way, to put byte mp3 data into a audioclip. So I'm stuck with that solution too ;(