gpt4 book ai didi

c# - Powershell Cmdlet - 为什么一次处理一个字符串 [] 参数元素?

转载 作者:行者123 更新时间:2023-12-04 08:08:11 25 4
gpt4 key购买 nike

我正在开发一个 Powershell 模块,该模块需要调用一个接受字符串列表参数的 .NET 方法。该方法基于字符串集合构造一个 REST URL,以在单个 API 调用中检索列表中所有元素的结果:

var MyAPIConnector = new APIConnector();
var elements = File.ReadAllLines(@"C:\temp\myfile.txt").ToList();
List<ApiResult> Result = MyAPIConnector.GetResult(elements);
此代码在几秒钟内执行。
在我的 Powershell 模块中,相同的操作需要更长的时间。以下是模块的编码方式:
[Cmdlet(VerbsCommon.Get, "ApiResult")]
[OutputType(typeof(ApiResult))]
public class GetApiResults : Cmdlet
{
[Parameter(Mandatory = true, ValueFromPipeline = true)]
public string[] Identity {get; set;}

private List<string> Input;
private List<ApiResult> Result;

protected override void BeginProcessing()
{
base.BeginProcessing();
}

protected override void ProcessRecord()
{
base.ProcessRecord();
Result = MyAPIConnector.GetResult(Identity.ToList());
WriteObject(Result);
}
}
如果我以与示例程序相同的方式使用我的 Cmdlet:
$Result = Get-Content -Path 'C:\temp\myfile.txt' | Get-ApiResult
返回相同的结果,但速度要慢得多。通过调试,我能够确定,尽管在我的 Cmdlet 源代码中,我使用 Linq 将字符串数组 Identity 转换为 List,但 MyAPIConnector.GetResult() 正在为数组的每个元素单独调用!谁能解释这是为什么?

最佳答案

更新:更正-我错误地写了这篇文章,暗示在使用 -OutBuffer 时对象被缓冲进来,这是没有意义的。一次只能处理来自管道的 1 个入站对象。但是,您可以使用 OutBuffer 参数来控制从 cmdlet 沿管道向下发送的对象数量,如下所述。但是,OutBuffer 对您的问题没有任何帮助:) 正如下面最后一段中所建议的,您可以调用您的 cmdlet 并将您的字符串数组直接作为参数提供给 -Identity,这将允许您以如下方式使用 Linq你要。
现在介绍一下 OutBuffer :)
有一个常用的参数叫做 -OutBuffer这将需要一个整数来定义它在输出之前持有的对象的数量。尽管如此,每个对象将在收到时单独处理。结果将被缓冲,直到满足给定的 OutBuffer + 1 或没有更多对象。
考虑以下示例
我将使用下面的测试函数来演示

Function Test-PipelineInput
{
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline = $true)]
[string[]]$Identity
)

Process {
if ($Identity){
foreach ($item in $Identity) {
$item
}
Write-Host "---End process block"
}
}
}
没有 -OutBuffer
$Gettysburg | Select -First 9 | Test-PipelineInput 

Four score and seven years ago our
---End process block
fathers brought forth on this continent,
---End process block
a new nation, conceived in Liberty, and
---End process block
dedicated to the proposition that all
---End process block
men are created equal.
---End process block
Now we are engaged in a great
---End process block
civil war, testing whether that
---End process block
nation, or any nation so conceived
---End process block
and so dedicated, can long endure.
---End process block
使用 -Outbuffer 2(缓冲区 2 和 3 号进程)
$Gettysburg | Select -First 9 | Test-PipelineInput -OutBuffer 2

---End process block
---End process block
Four score and seven years ago our
fathers brought forth on this continent,
a new nation, conceived in Liberty, and
---End process block
---End process block
---End process block
dedicated to the proposition that all
men are created equal.
Now we are engaged in a great
---End process block
---End process block
---End process block
civil war, testing whether that
nation, or any nation so conceived
and so dedicated, can long endure.
---End process block
因此,您可以在此处看到进程 block 如何在前 2 个接收到的对象中不接收任何对象,然后在第 3 个接收对象,依此类推。
更新:更正 - 进程 block 将在接收到每个单独的对象时运行并保持输出对象,直到缓冲区 + 1 个对象排队 .这仍然不会给你你想要的东西。如果您希望使用 Linq 一次将整个数组发送到函数中,下面的选项是不使用管道的选项
此外,除了通过管道发送对象之外,您也可以将其作为参数传递给您的 -Identity 参数,您的函数将在该参数中接收完整的字符串数组并对其进行完全处理
Test-PipelineInput -Identity ( $Gettysburg | Select -First 15 )

Four score and seven years ago our
fathers brought forth on this continent,
a new nation, conceived in Liberty, and
dedicated to the proposition that all
men are created equal.
Now we are engaged in a great
civil war, testing whether that
nation, or any nation so conceived
and so dedicated, can long endure.
We are met on a great battle-field
of that war. We have come to dedicate
a portion of that field, as a final
resting place for those who here gave
their lives that that nation might
live. It is altogether fitting and
---End process block
最后一个更新:
添加一元数组运算符(数组前面的逗号)将允许将数组通过管道传送到下一个命令。我最初认为这不起作用,但这是另一回事。
,($Gettysburg | Select-Object -First 15) | Test-PipelineInput

Four score and seven years ago our
fathers brought forth on this continent,
a new nation, conceived in Liberty, and
dedicated to the proposition that all
men are created equal.
Now we are engaged in a great
civil war, testing whether that
nation, or any nation so conceived
and so dedicated, can long endure.
We are met on a great battle-field
of that war. We have come to dedicate
a portion of that field, as a final
resting place for those who here gave
their lives that that nation might
live. It is altogether fitting and
---End process block
有关更多信息,请参阅这篇文章
Pipe complete array-objects instead of array items one at a time?

关于c# - Powershell Cmdlet - 为什么一次处理一个字符串 [] 参数元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66111936/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com