Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

ReadToEnd() makes unity3d freeze up when trying to use an external process.

Discussion in 'Scripting' started by Morichalion, Oct 19, 2016.

  1. Morichalion

    Morichalion

    Joined:
    Mar 21, 2011
    Posts:
    9
    I'm wanting to build something for Christmas this year.

    Basic idea is that I'd use a Unity app as a front-end, and use it to control hardware similar to 3d printer. Hardware is on order, so I thought I'd try to get a head start trying to make the software work using my existing 3d printer.

    I read up on the Process class as it seemed to be the thing I'd need to make Unity3d talk to Pronsole. The problem is, any attempt to use the ReadToEnd() method freezes Unity. I can use ReadLine() to get the information line-by-line, but as soon as it gets to the end of the list, Unity freezes up.

    I don't really NEED to read the output from Pronsole.... but it would be nice to know if I just screwed that part up or something. Or, maybe there's something wrong with Pronsole? o.o

    Code (CSharp):
    1.     void Update () {
    2.         if (Input.GetMouseButtonDown (0)) {
    3.             //ReadToEnd makes it freeze up. ReadLine() works until it gets to the end of the lines,
    4.             //then it freezes.
    5.             DEB = Proc.StandardOutput.ReadToEnd ();
    6.         }
    7.     }
    8.     IEnumerator PStart(){
    9.         Proc = new Process ();
    10.         /*
    11.         Setting up the process. I want redirect everything to unity so I can manage it from my
    12.         application.
    13.         */
    14.         Proc.StartInfo.UseShellExecute = false;
    15.         Proc.StartInfo.RedirectStandardOutput = true;
    16.         Proc.StartInfo.RedirectStandardError = true;
    17.         Proc.StartInfo.RedirectStandardInput = true;
    18.        
    19.         //Proc.StartInfo.CreateNoWindow = true;
    20.         Proc.StartInfo.FileName = "C:\\Path\\To\\pronsole.exe";
    21.  
    22.  
    23.         yield return null;
    24.     }
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,560
    this is basically a .net/mono question, not really a unity question... so lets go to the appropriate sources.

    So you knew to redirect the output stream so you can capture it... lets look at that documentation:
    https://msdn.microsoft.com/en-us/li...artinfo.redirectstandardoutput(v=vs.110).aspx

    Furthermore, it's "freezing" Unity, a method being called in Update is doing this... this usually means you called a blocking method that isn't returning forwhatever reason. This can happen for example if waiting for an asynchronous action to complete...... like another 'process' to complete.

    So, in said documentation lets look for discussion about synchronisity:

    So we can use BeginOutputReadLine to asynchronously read, and not have to wait for the process to complete.

    Lets go there:
    https://msdn.microsoft.com/en-us/li...cs.process.beginoutputreadline(v=vs.110).aspx

    Here we can find example code to implement it.

    Only downside is that this is now an asynchronous callback, this means the event won't occur on the main Unity thread. And if you try to access Unity specific stuff outside of the thread, you often get errors because Unity doesn't like that.

    So you should look into jumping back to the main thread from there. This can easily be done by just updating a string, and then back in Update you actually push to the display that string.