C#Process DataReceivedEventHandler只能运行一次

问题描述 投票:0回答:1

我有一个Unity应用程序,它创建一个尝试通过adb shell向Android设备发送命令的进程。我可以在应用程序的过程中发送命令。但我第一次只收到Android设备的输出。我不知道它是否与OutputDataReceived有缓冲问题。输入通过但我在Unity编辑器上没有收到任何日志。如果我将Process.StartInfo.CreateNoWindow变为true,我可以看到在Unity外部生成的adb shell中的所有输出。首次执行后,输出不会从该控制台重定向到Unity。

    public void StartShellProcessAsync ()
    {
        ShellThread = new Thread(() =>
        {
            ShellProcess = new Process();
            ShellProcess.StartInfo.FileName = "adb.exe";
            ShellProcess.StartInfo.Arguments = "shell";

            ShellProcess.StartInfo.CreateNoWindow = false;
            ShellProcess.StartInfo.UseShellExecute = false;

            ShellProcess.StartInfo.RedirectStandardOutput = true;
            ShellProcess.StartInfo.RedirectStandardError = true;
            ShellProcess.StartInfo.RedirectStandardInput = true;

            ShellProcess.EnableRaisingEvents = true;
            ShellProcess.OutputDataReceived += new DataReceivedEventHandler(OnOutputDataReceived);
            ShellProcess.ErrorDataReceived += new DataReceivedEventHandler(OnErrorDataReceived);

            ShellProcess.Exited += new EventHandler(OnProcessExited);

            ShellProcess.Start();
            ShellProcess.BeginOutputReadLine();
            ShellProcess.BeginErrorReadLine();
            ShellProcess.WaitForExit();
        });
        ShellThread.Start();
    }

我在Unity中有按钮发送如下命令:

am start -m <application activity>
am stack list

我试图读取am stack list的输出它是否有效,如果它是我发出的第一个命令。但是如果我在am start -m <application activity>之后运行它,输出就不会通过Unity了。

我在一个线程中运行ShellProcess的原因是让整个应用程序执行过程保持打开状态。我不想为我发送到Android的每个命令生成一个新进程,因为它很耗时。

c# .net multithreading unity3d process
1个回答
0
投票

尝试锁定你的线程。这可确保一次只有一个进程处于活动状态。

如果在另一个线程忙于执行相同的过程时调用新线程,则会发生一些冲突。

private readonly object balanceLock = new object();

//Place this code elsewhere
private void Instantiate_Shell_Once()
{

        ShellProcess = new Process();
        ShellProcess.StartInfo.FileName = "adb.exe";
        ShellProcess.StartInfo.Arguments = "shell";

        ShellProcess.StartInfo.CreateNoWindow = false;
        ShellProcess.StartInfo.UseShellExecute = false;

        ShellProcess.StartInfo.RedirectStandardOutput = true;
        ShellProcess.StartInfo.RedirectStandardError = true;
        ShellProcess.StartInfo.RedirectStandardInput = true;

        ShellProcess.EnableRaisingEvents = true;
        ShellProcess.OutputDataReceived += new DataReceivedEventHandler(OnOutputDataReceived);
        ShellProcess.ErrorDataReceived += new DataReceivedEventHandler(OnErrorDataReceived);

        ShellProcess.Exited += new EventHandler(OnProcessExited);

}

public void StartShellProcessAsync ()
{
    ShellThread = new Thread(() =>
    {
        lock(balanceLock)
        {

        ShellProcess.Start();
        ShellProcess.BeginOutputReadLine();
        ShellProcess.BeginErrorReadLine();
        ShellProcess.WaitForExit();

       }
   });
   ShellThread.Start();
}
© www.soinside.com 2019 - 2024. All rights reserved.