【发布时间】:2014-08-17 03:14:46
【问题描述】:
如何停止执行在 ProcessRecord 方法中接受管道输入的 cmdlet。如果 ProcessRecord 中的某个条件不满足,我需要立即停止执行并返回一个false:
protected override void BeginProcessing()
{
_output = true;
}
protected override void ProcessRecord()
{
//processing
if(condtion == true) return;
_output = false;
//How do I stop processing now, and ensure _output is returned as result?
}
protected override void EndProcessing()
{
WriteObject(_output);
}
PipelineStoppedException 似乎有效,但没有给出确切的行为。
更新了一个更具体的例子,使用PipelineStoppedException:
让我们考虑一个 cmdlet First-List,它的行为应该类似于 LINQ 中的 First()。此 cmdlet 的实现如下:
[Cmdlet("First", "List")]
public class FirstList : Cmdlet
{
[Parameter(Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
public object Input { get; set; }
[Parameter(Position = 0, Mandatory = true)]
public ScriptBlock ScriptBlock { get; set; }
protected override void ProcessRecord()
{
var output = ScriptBlock.InvokeWithContext(null, new List<PSVariable>
{
new PSVariable("input", Input),
})[0];
if (output.ToString() != "True") return;
WriteObject(Input);
throw new PipelineStoppedException();
}
protected override void EndProcessing()
{
Error.NoMatch();
}
}
有了Select -First,我可以做到以下几点:
$a = 1..10 | Select -First 1
#$a is 1
但我的实现:
$a = 1..10 | First-List { $input -ge 5 }
#$a should be assigned 5, but it is not
但1..10 | First-List { $input -ge 5 } 确实输出了 5。
更新 2:
看起来Select-Object 实际上抛出了StopUpstreamCommandsException。
还有一个反馈可以在这里提供 - https://connect.microsoft.com/PowerShell/feedback/details/768650/enable-users-to-stop-pipeline-making-stopupstreamcommandsexception-public
【问题讨论】:
-
已经提到的 PipelineStoppedException 是停止整个管道的方式。不过,它确实确实停止了事情。例如,如果你在 PS4 上这样做:
dir | move -destination C:\otherfolder -passthru | select -first 10,Select-Object 将抛出 PipelineStoppedException 并且只会移动前 10 个文件。如果这就是你所追求的,那就完美了。否则,您需要解释“停止执行”的含义;-) -
@Jaykul - 谢谢。请查看我更新的问题,了解更多详情以及为什么
PipelineStoppedException似乎不适合我。
标签: c# powershell