我正在使用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#可以处理所有场景吗?
答案 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。