- Home /
How to make functions async?
Hi everyone,
I have an expensive function that takes 3-4 seconds to complete. When I call this function inside of a script it, app freezes for 3-4 seconds till the result back. I have searched and seen async/await/task method. It says it is like javascript async/await but I coudn't make it work. Like in javascript can I make my expensive function async so that it works in the background without freezing my unity app? How can I make function async and wait result in coroutine yield return or await?
public void ExpensiveFunction()
{
// Lots of operations.
}
IEnumerator MyCoroutine()
{
await MyResult = ExpensiveFunction();
}
Answer by Pangamini · May 24, 2019 at 01:07 PM
You can start a pooled thread execution using BeginInvoke(). Then, wait for the result in a coroutine
// this is a coroutine body
{
// concurrently run something
System.Func<string> concurrentMethod = ExpensiveThreadedFunction;
var concurrentResult = concurrentMethod.BeginInvoke(null, null);
while (!concurrentResult.IsCompleted)
{
yield return Waits.waitForEndOfFrame;
}
string expensiveResult = concurrentMethod.EndInvoke(concurrentResult);
Debug.Log(expensiveResult );
}
string ExpensiveThreadedFunction()
{
// do something that takes very long
}
You can wait any arbitrary amount of time in the loop, if you think it's expensive to check for operation completion every frame
This way can't solve the app freeze issue because you're trying to cast all function and your waitforendofframe only wait for log not function :D he needs to seperate his function this is only way i know
Oh you misunderstand the concept, really. BeginInvoke will execute the deletage on another thread. Until the threaded execution is complete, the coroutine spins in the loop, leaving the app responsive. Afrer the threaded execution is complete, the return value is retrieved using EndInvoke, and the execution of the coroutine continues (on the main thread ofc)
Dude, move the EXPENSIVE Function to another thread is not enough do you think another thread can handle it without freeze? You can't know that and he says he had 4-5 second freeze this mean is function is not expensive is SO EXPENSIVE
Please. Yes, that's exactly why it won't freeze. Because it runs concurrently on another thread. Just because you don't know the soludiuon, you don't have to imply that it doesn't exist. I've copied this code (and renamed the methods) from my production code where I am generating super long JSONs, exactly for the purpose of NOT freezing the main engine loop.
okay let's try this situations with expensive function and we can try my solution on main thread it's will be faster you will see:)
Sorry for late response I have been busy with another task. I will try your solution asap. Thank you!
Np. Of course, your expensive operation must be executable on another thread. If it depends on some scene data, texture data or something, you should collect that in the coroutine (or somewhere else on the main thread) and just run the computation that doesn't break unity rules about threaded access
Answer by dontdiedevelop · May 24, 2019 at 12:40 PM
IEnumerator ExpensiveFunction()
{
operation1();
yield return new WaitForSeconds(0.4f);
operation2();
}
As far as I understood you suggest me to break my expensive function into smaller operations and call yield return after each of them right? Problem is that is very large function and some operations are hard to break into smaller parts.
async functions works like this you can use it or not your choice
Not at all. You could do it in multiple ways. I would recommend a separate thread for executing this, or even better @Panga$$anonymous$$i ´s solution.
The IEnumerator will simply work in the same fram until it is done, and will do you no good, unless ExpensiveFunction can be spread out over multiple frames and then you just make Expensive function into a coroutine, and wait for a frame between every major operation.
Your answer
Follow this Question
Related Questions
Can you run a coroutine more often than Update? 1 Answer
How to load scene when async.progress is 0.9? 0 Answers
StartCoroutine and Yield 0 Answers