【问题标题】:Handle interactive prompt from child process处理来自子进程的交互式提示
【发布时间】:2012-06-25 14:46:24
【问题描述】:

我正在扩展一个 .NET4 命令行应用程序,其中包括创建一个外部进程来调用 svn.exe 以从我们的存储库中提取一些数据。问题是我们的账号密码修改后,认证失败,SVN提示输入账号密码。

SVN 通过向标准错误写入提示来做到这一点。输出如下:

标准输出:更新“。”: STDERR:身份验证领域: VisualSVN 服务器 STDERR:“joe.smith”的密码:

我认为出错的地方是子进程(此后称为 CP)的第二个“行”不包含换行符,并且可能没有被 BeginErrorReadLine( ) 在标准输入流上的父进程 (PP) 阻塞之前。我的猜测得到了以下事实的支持:关闭 CP 上的输入流会导致输出流和错误流中剩余的数据由我的 DataReceivedEventHandler 回调处理。

事件的顺序似乎是:

  1. CP 开始写入 STDOUT。
  2. 如果缓存的身份验证凭据错误,CP 开始将上述消息写入 STDERR。
  3. 根据我是从 STDERR 同步读取还是异步读取,会发生以下情况:
    • 同步:CP 似乎在等待来自 STDIN 的输入,而 PP 等待来自 STDERR 的更多数据。即使偷看或检查流是否关闭也会导致死锁。
    • 异步:在 CP 等待从其 STDIN 读取之前,不读取第二行。

假设我已经正确诊断出问题,我仍然不知道该怎么做。

至于我尝试过的选项:

  • this MSDN article 之后,我尝试从标准错误中同步读取。这似乎充满了危险,因为任何方法只要读取标准错误的最后一个字符就会无限期地阻塞。
  • 上一个链接还建议“或者,您可以通过创建两个线程并在单独的线程上读取每个流的输出来避免死锁情况。”,但是我在这条轨道上的努力显然是相当误导。当我知道我已经到达流的末尾时,我看不出线程如何提供帮助,但为时已晚。

澄清一下,我怎样才能安全地读到标准错误流的末尾而不会导致死锁?

【问题讨论】:

    标签: .net process stream synchronization deadlock


    【解决方案1】:

    我认为你的分析是正确的。我不得不做一些 CP stdio 重定向,这在 Win32 上总是很痛苦(设计为 UI 平台而不是命令行......)。

    无论如何,您可以尝试从实际流中读取数据(使用 BeginRead,如果 .NET 4.5 则使用 ReadAsync)并自己进行 Encoding 转换。那将是我的第一次尝试。

    否则,您将不得不使用多个线程。我以前做过,很痛苦。

    无论哪种方式,您实际上都不是在等待 CP 的标准错误结束。只需为您的魔线监控它。大多数控制台程序在退出之前不会关闭它们的 stdout 或 stderr,因此在它退出之前你不能一直读到最后。

    【讨论】:

    • 您认为切换到同步阅读 STDERR 是否值得?这似乎是我可以在第二个“行”(包含“'joe.smith'的密码”的那个)的唯一方法,它会给我更多的控制权,所以我可以将它与对 STDIN 的写入进行协调.
    • 就个人而言,我会异步读取流。如果您使用 VS2010 的 Async CTP 或 VS2012 的 Async Targeting Pack,这会更容易。
    猜你喜欢
    • 1970-01-01
    • 2017-09-19
    • 2015-03-14
    • 1970-01-01
    • 2021-04-30
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多