【问题标题】:C# Process DataReceivedEventHandler works only onceC# Process DataReceivedEventHandler 只工作一次
【发布时间】:2018-08-31 18:21:26
【问题描述】:

我有一个 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 &lt;application activity&gt; 之后运行它,则输出不会传递到 Unity。

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

【问题讨论】:

    标签: c# .net multithreading unity3d process


    【解决方案1】:

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

    如果在另一个线程忙于执行相同的进程时调用了一个新线程,则会出现一些冲突。

    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();
    }
    

    【讨论】:

    • 这似乎没有帮助。执行此操作时也看不到任何错误。
    • @Anril 我认为你需要删除线程内的一些代码,除了 `ShellProcess.Start(); ShellProcess.BeginOutputReadLine(); ShellProcess.BeginErrorReadLine(); ShellProcess.WaitForExit(); 可能外壳是多次创建的。只需执行这些代码一次。
    • 我无法再次测试。到时候我会告诉你的。
    猜你喜欢
    • 2018-06-22
    • 2020-08-05
    • 1970-01-01
    • 2017-01-06
    • 2018-06-22
    • 2015-09-18
    • 2013-12-31
    • 1970-01-01
    • 2013-09-28
    相关资源
    最近更新 更多