从c#中的进程的StandardOutput读取数据时有最大超时

时间:2013-06-19 16:59:43

标签: c# process phantomjs

我正在使用c#启动一个进程(实际上是phantomjs),并尝试通过标准输出传递信息(base64image字符串)。 如果这个过程成功,一切顺利。 如果进程失败(在这种情况下,因为页面幻像中的javascript错误正在打开),它会无限期挂起。

我的代码如下所示:

var path = Server.MapPath("phantomjs.exe");
var args = string.Join(" ", new[] { Server.MapPath(@"screenshot.js"), url });

var info = new ProcessStartInfo(path, args);
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
info.CreateNoWindow = true;

var p = Process.Start(info);

// it hangs on the following line:
var base64image = p.StandardOutput.ReadToEnd();
bytes = Convert.FromBase64CharArray(base64image.ToCharArray(), 0, base64image.Length);

我假设运行任何外部进程都可能导致此问题。 如果该过程没有正确完成(无论出于何种原因),那么将永远不会有一个输出结束(可能是?)。

我想知道的是,如何引入最大超时?如果该过程成功并且在超时时间内退出,那很好。如果没有,请终止该过程并执行其他操作。

我尝试了以下内容:

if (p.WaitForExit(30000))
{
    var base64image = p.StandardOutput.ReadToEnd();
    bytes = Convert.FromBase64CharArray(base64image.ToCharArray(), 0, base64image.Length);

    // do stuff with bytes
}
else
{
    p.Kill();

    // do something else
}

当我运行一个更简单的应用程序(它只是每秒钟向控制台写一个数字60秒)时,这是有效的。 当我尝试使用phantomjs时,它会失败(等待30秒)以查找应该工​​作的情况(当我恢复原始代码或从控制台运行时,花费的时间少于30秒)。

也许phantomjs(或我编写的js脚本)没有正确退出,但c#可以处理所有场景吗?

1 个答案:

答案 0 :(得分:1)

您必须在脚本中添加全局错误处理程序。 当存在JavaScript执行错误(解析,异常,......)时,phantomjs不会自行退出。请在一个简单的脚本中自己尝试。

有一个非常基本的例子here

phantom.onError = function(msg, trace) {
    var msgStack = ['PHANTOM ERROR: ' + msg];
    if (trace && trace.length) {
        msgStack.push('TRACE:');
        trace.forEach(function(t) {
            msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function + ')' : ''));
        });
    }
    console.error(msgStack.join('\n'));
    phantom.exit(1);
};

此外,您还可以添加page error handler

page.onError = function(msg, trace) {
    var msgStack = ['ERROR: ' + msg];
    if (trace && trace.length) {
        msgStack.push('TRACE:');
        trace.forEach(function(t) {
            msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function + '")' : ''));
        });
    }
    console.error(msgStack.join('\n'));
};

请注意,当WebPage#onError处理程序出现JavaScript执行错误未捕获时,会调用phantom.error。