- Home /
why this code is making unity unresposnive?
using System.Threading.Tasks;
using UnityEngine;
public class sampleclass : MonoBehaviour
{
bool istrue = true;
void Start()
{
Invoke("hello_false", 5);
Task<string> result = call();
Debug.Log("is code working" + result.Result);
}
void hello_false()
{
istrue = false;
}
void hello()
{
while (istrue)
{
int justcount = 0;
justcount++;
}
}
async Task<string> call()
{
Task newtask = new Task(hello);
newtask.Start();
await newtask;
return "task done ";
}
}
when I don't use return statement code runs perfectly but when i add return statement it hangs/become unresponsive.
sorry i don't know enough about async 's
only way i've used them is like so..
public static AsyncOperation async;
public static $$anonymous$$onoBehaviour monoBehaviour;
/// <summary>
/// Loads the scene with async basic.
/// </summary>
/// <param name="levelIndex">Level index.</param>
public void LoadNextSceneWithAsync ()
{
int currentScene = Scene$$anonymous$$anager.GetActiveScene ().buildIndex;
if (!Equals (Scene$$anonymous$$anager.GetActiveScene ().buildIndex, $$anonymous$$ainGame$$anonymous$$anager.LoadingScene)) {
Scene$$anonymous$$anager.LoadScene ($$anonymous$$ainGame$$anonymous$$anager.LoadingScene);
if(Equals (LoadingPanel,null))
LoadingPanel = GameObject.Find ("LoadingPanel").gameObject;
LoadingPanel.SetActive (true);
AutoLoadNextLevelWithAsync (Scene$$anonymous$$anager.GetSceneAt (currentScene).buildIndex);
} else {
if(Equals (LoadingPanel,null))
LoadingPanel = GameObject.Find ("LoadingPanel").gameObject;
LoadingPanel.SetActive (true);
AutoLoadNextLevelWithAsync (Scene$$anonymous$$anager.GetSceneAt (currentScene).buildIndex);
}
}
/// <summary>
/// Autos the load next level with async.
/// </summary>
/// <param name="levelIndex">Level index.</param>
public static void AutoLoadNextLevelWithAsync (int currentScene)
{
if (Instance.AutoloadNextLevel && !Instance.AddWaitTimer) {
monoBehaviour.StartCoroutine (ILoadNextSceneAfterTimeWithAsync (Scene$$anonymous$$anager.GetSceneAt (currentScene).buildIndex, 0.2f));
} else {
monoBehaviour.StartCoroutine (ILoadNextSceneAfterTimeWithAsync (Scene$$anonymous$$anager.GetSceneAt (currentScene).buildIndex, 0));
}
}
/// <summary>
/// Is the load next scene after time with async.
/// </summary>
/// <returns>The load next scene after time with async.</returns>
/// <param name="sceneName">Scene name.</param>
/// <param name="waitTime">Wait time.</param>
public static IEnumerator ILoadNextSceneAfterTimeWithAsync (string sceneName, float waitTime)
{
yield return new WaitForSeconds (waitTime);
monoBehaviour.StartCoroutine (ILoadSceneWithProgressBar (Scene$$anonymous$$anager.GetSceneByName (sceneName).buildIndex + 1));
}
/// <summary>
/// Loads the scene with progress bar.
/// </summary>
/// <returns>The scene with progress bar.</returns>
/// <param name="sceneNameToLoad">Scene name to load.</param>
private static IEnumerator ILoadSceneWithProgressBar (int level)
{
Image progressBar = GameObject.FindWithTag ("FillerImage").GetComponent<Image> ();
Instance.async = Scene$$anonymous$$anager.LoadSceneAsync (level);
while (!Instance.async.isDone) {
progressBar.fillAmount = Instance.async.progress;
yield return null;
}
if (Instance.async.isDone) {
if(Equals (LoadingPanel,null))
LoadingPanel = GameObject.Find ("LoadingPanel").gameObject;
LoadingPanel.SetActive (false);
}
}
Answer by KenanTheFab · Feb 21, 2019 at 06:45 PM
It seems to loop
void hello()
over and over due to
while(istrue)
And nothing really tells it to stop the loop.
Your answer is not true.
void hello_false()
{
istrue = false;
}
Does exactly that.
He is right though. istrue gets set to false every 5 seconds. BUT unity is calling the while(istrue) every frame and it calls it infinite amount of time in one frame during a second, so it just loops over and over and never allows istrue to get set to false.
it has noting to do with while loop.I have tried this result but still unity editor become unresponsive.i think its due to return statement but i don't have any reason for it.
using System.Threading.Tasks;
using UnityEngine;
public class sampleclass : $$anonymous$$onoBehaviour
{
void Start()
{
Task<string> result = call();
Debug.Log("is code working" + result.Result);
}
void hello()
{
for (int i = 0; i < 10; i++)
{
int timewaste = 0;
timewaste++;
}
}
async Task<string> call()
{
Task newtask = new Task(hello);
newtask.Start();
await newtask;
return "task done ";
}
}
Answer by Kishotta · Feb 21, 2019 at 09:56 PM
It might be better to stick with coroutines and use an Action callback:
private bool isTrue = true;
private void Start () {
// When 'Call()' completes it will log the result
StartCoroutine (Call (result => Debug.Log (result)))
// Kick off the kill condition
StartCoroutine (SetFalse ());
}
private IEnumerator Call (Action<string> callback) {
// When 'Hello()' completes, it returns the string "Task Complete 682" to the initial lambda
yield return Hello (finalCount => callback ("Task Complete " + finalCount));
}
private IEnumerator Hello (Action<int> callback) {
int count = 0;
while (isTrue) {
count++;
yield return null;
}
// Returns the count to the above lambda
callback (count);
}
// Just a delayed operation
private IEnumerator SetFalse () {
yield return WaitForSeconds (5f);
isTrue = false;
}
I don't want to use coroutine as they return values.I know i can use callbacks but I would rather prefer async and await.also I wanted the reason for this behavior.thanks for help
Answer by wildDevelop · Oct 20, 2021 at 11:55 AM
Your problem shoud be on start function, you also need to use async for Start() and await for call(), not sure what are you trying to achive but here is the correct code :
bool istrue = true;
async void Start()
{
Invoke("hello_false", 5);
var finalResult = await call();
Debug.Log("is code working " + finalResult);
}
void hello_false()
{
istrue = false;
}
void hello()
{
while (istrue)
{
int justcount = 0;
justcount++;
}
}
async Task<string> call()
{
Task newtask = new Task(hello);
newtask.Start();
await newtask;
return "task done ";
}
Your answer
