I ended up with the following solution. I did not find a way to load raw file main thread, but I managed to load it in Coroutine and perform further (also heavy) operations on this file on a background Thread. I made a static method like this:
public static void ReadAllBytesInCoroutine(MonoBehaviour context, string filePath, Action<ReadBytesInCoroutineResult> onComplete)
{
context.StartCoroutine(ReadFileBytesAndTakeAction(filePath, onComplete));
}
private static IEnumerator ReadFileBytesAndTakeAction(string filePath, Action<ReadBytesInCoroutineResult> followingAction)
{
WWW reader = null;
try
{
reader = new WWW(filePath);
}
catch(Exception exception)
{
followingAction.Invoke(ReadBytesInCoroutineResult.Failure(exception));
}
while (reader != null && !reader.isDone)
{
yield return null;
}
followingAction.Invoke(ReadBytesInCoroutineResult.Success(reader.bytes));
}
ReadBytesInCoroutineResult is my simple, custom data class:
public class ReadBytesInCoroutineResult
{
public readonly bool successful;
public readonly byte[] data;
public readonly Exception reason;
private ReadBytesInCoroutineResult(bool successful, byte[] data, Exception reason)
{
this.successful = successful;
this.data = data;
this.reason = reason;
}
public static ReadBytesInCoroutineResult Success(byte[] data)
{
return new ReadBytesInCoroutineResult(true, data, null);
}
public static ReadBytesInCoroutineResult Failure(Exception reason)
{
return new ReadBytesInCoroutineResult(true, null, reason);
}
}
This way I have a mechanism to order to load a file in coroutine in any place (as long as it is on the main thread). A file is loaded synchronously, but it is not blocking main thread, because of the coroutine. Later I invoke this function and take acquired bytes on a separate thread, where I perform heavy computing on them.
ResourcesUtils.ReadAllBytesInCoroutine(monoBehavior, filePath, (bytes) => {
//here I run an async method which takes bytes as parameter
});