jkf*_*kff 6 .net streaming powershell
我的程序执行用户指定的脚本块,我希望它以递增方式返回其输出(例如,如果脚本块运行很长时间).
但是,ScriptBlock的API似乎没有暴露任何管道相关的东西!
它有一些看起来像我需要的函数(InvokeWithPipe),但它们是内部的,它们的参数是内部类型.我不想在这里诉诸于反思.
那么,有没有办法访问scriptblock的管道?也许某种强大的解决方法?
这里有一些代码将向ScriptBlock添加一个扩展方法来流输出,为每个输出对象调用一个委托.这是真正的流式传输,因为对象不会在集合中备份.这适用于PowerShell 2.0或更高版本.
public static class ScriptBlockStreamingExtensions {
public static void ForEachObject<T>(
this ScriptBlock script,
Action<T> action,
IDictionary parameters) {
using (var ps = PowerShell.Create()) {
ps.AddScript(script.ToString());
if (parameters != null) {
ps.AddParameters(parameters);
}
ps.Invoke(Enumerable.Empty<object>(), // input
new ForwardingNullList<T>(action)); // output
}
}
private class ForwardingNullList<T> : IList<T> {
private readonly Action<T> _elementAction;
internal ForwardingNullList(Action<T> elementAction) {
_elementAction = elementAction;
}
#region Implementation of IEnumerable
// members throw NotImplementedException
#endregion
#region Implementation of ICollection<T>
// other members throw NotImplementedException
public int Count {
get {
return 0;
}
}
#endregion
#region Implementation of IList<T>
// other members throw NotImplementedException
public void Insert(int index, T item) {
_elementAction(item);
}
#endregion
}
}
Run Code Online (Sandbox Code Playgroud)
例:
// execute a scriptblock with parameters
ScriptBlock script = ScriptBlock.Create("param($x, $y); $x+$y");
script.ForEachObject<int>(Console.WriteLine,
new Dictionary<string,object> {{"x", 2},{"y", 3}});
Run Code Online (Sandbox Code Playgroud)
(2011/3/7更新,参数支持)
希望这可以帮助.
| 归档时间: |
|
| 查看次数: |
445 次 |
| 最近记录: |