Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

process.OutputDataReceived not read all lines [closed]

Tags:

c#

result from cmd

C:\Users\XXXXX>adb start-server
* daemon not running. starting it now *
* daemon started successfully *

C:\Users\XXXXX>

my c# code.

public string devicesPlus()
{
    psi.Arguments = "start-server";
    call = Process.Start(psi);
    call.OutputDataReceived += new DataReceivedEventHandler(call_OutputDataReceived);
    call.ErrorDataReceived += new DataReceivedEventHandler(call_OutputDataReceived);
    call.EnableRaisingEvents = true;
    call.Exited += new EventHandler(call_Exited);
    call.Start();
    call.BeginOutputReadLine();
    call.BeginErrorReadLine();
    call.StandardInput.Close();
    call.WaitForExit();
    return outData.ToString();
}

private void call_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    if (e.Data != null)
    {
        outData.Append(e.Data);
    }
}

Now when i call devicesPlus,some time i get only * daemon not running. starting it now * some time it's just working in background and no result.. can you guys tell me whats wrong in my code,why i don't get correct return like cmd.. new to c# sorry for bad english...

Update if i kill adb from outside my app i get reply from my software suddenly.

like image 949
user1965804 Avatar asked Jan 24 '26 01:01

user1965804


1 Answers

WaitForExit() only waits for the process to exit. It does not wait for your process to receive all output, so you have a race condition there.

call_OutputDataReceived will get called with e.Data == null to signify the end of the output. You need to wait for that call before using outData.ToString().

For example, you could use a new CountdownEvent(2) to wait for the end of the two streams:

    CountdownEvent countdownEvent;
    
    public string devicesPlus()
    {
        psi.Arguments = "start-server";
        countdownEvent = new CountdownEvent(2);
        call = Process.Start(psi);
        call.OutputDataReceived += new DataReceivedEventHandler(call_OutputDataReceived);
        call.ErrorDataReceived += new DataReceivedEventHandler(call_OutputDataReceived);
        call.EnableRaisingEvents = true;
        call.Exited += new EventHandler(call_Exited);
        call.Start();
        call.BeginOutputReadLine();
        call.BeginErrorReadLine();
        call.StandardInput.Close();
        call.WaitForExit();
        countdownEvent.Wait();
        return outData.ToString();
    }

    private void call_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (e.Data != null)
        {
            // prevent race condition when data is received form stdout and stderr at the same time
            lock (outData)
            {
                outData.Append(e.Data);
            }
        }
        else
        {
            // end of stream
            countdownEvent.Signal();
        }
    }
like image 96
Daniel Avatar answered Jan 25 '26 15:01

Daniel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!