Powershell 接收作业如何保持正确的记录顺序

Powershell 接收作业如何保持正确的记录顺序,powershell,powershell-jobs,Powershell,Powershell Jobs,我试图了解接收工作是如何在内部工作的。在下面的代码中,我可以看到Job对象保存来自不同数据流的记录的位置: $InformationPreference = 'SilentlyContinue' $sb = { $VerbosePreference = 'Continue' $InformationPreference = 'Continue' $WarningPreference = 'Continue' Write-Warning 'warning1'

我试图了解接收工作是如何在内部工作的。在下面的代码中,我可以看到Job对象保存来自不同数据流的记录的位置:

$InformationPreference = 'SilentlyContinue'

$sb = {
    $VerbosePreference = 'Continue'
    $InformationPreference = 'Continue'
    $WarningPreference = 'Continue'

    Write-Warning 'warning1'
    Write-Information 'information1'
    Write-Warning 'warning2'
    Write-Information 'information2'
    Write-Verbose 'verbose1'
    Write-Information 'information3'
}

$job = Start-Job -ScriptBlock $sb | Wait-Job

# my messages are here:
$job.ChildJobs[0].Verbose.Count     # prints 1
$job.ChildJobs[0].Information.Count # prints 3, only InformationRecord has TimeGenerated property
$job.ChildJobs[0].Warning.Count     # prints 2

Receive-Job $job

# prints:
# WARNING: warning1
# information1
# WARNING: warning2
# information2
# VERBOSE: verbose1
# information3
但我如何编写自己版本的Receive Job并保持不同消息的原始顺序呢?我试图检查源代码,但没有太多意义:

private void WriteJobResults(作业)
{
// ...
集合输出=ReadAll(job.output);
foreach(输出中的PSObject o)
{
// ... 
写对象(o);
}
Collection errorRecords=ReadAll(job.Error);
foreach(错误记录中的错误记录e)
{
// ...
mshCommandRuntime.WriteError(e,true);
}
Collection verbosecords=ReadAll(job.Verbose);
foreach(verboseRecords中的VerboseRecord v)
{
// ...
mshCommandRuntime.WriteVerbose(v,true);
}
//等其他流。。。
}
如前所述,我引用了错误的代码。这就是实际执行的内容:

// extract results and handle them
Collection<PSStreamObject> results = ReadAll<PSStreamObject>(job.Results);

if (_wait)
{
    foreach (var psStreamObject in results)
    {
        psStreamObject.WriteStreamObject(this, job.Results.SourceId);
    }
}
else
{
    foreach (var psStreamObject in results)
    {
        psStreamObject.WriteStreamObject(this);
    }
}
由于某些原因,
ObjectType=Verbose
不在集合中。我假设详细记录是从
MethodExecutor
记录中提取出来的。输出:

MethodExecutor
Warning Record: warning1
MethodExecutor
Information Record: information1
MethodExecutor
Warning Record: warning2
MethodExecutor
Information Record: information2
MethodExecutor
MethodExecutor
Information Record: information3
MethodExecutor
我找到了一个更好的方法,如何从工作中获得结果,但它只适用于新创造的工作。下面的代码为集合上的DataAdded事件添加事件处理程序:

$job = Start-Job -ScriptBlock $sb

$records = New-Object 'System.Collections.Generic.List[System.String]'

Register-ObjectEvent -InputObject $job.ChildJobs[0].Verbose -EventName 'DataAdded' -Action { $records.Add('verbose: ' + $Sender[$EventArgs.Index]) }.GetNewClosure() | Out-Null
Register-ObjectEvent -InputObject $job.ChildJobs[0].Information -EventName 'DataAdded' -Action { $records.Add('information: ' + $Sender[$EventArgs.Index]) }.GetNewClosure() | Out-Null
Register-ObjectEvent -InputObject $job.ChildJobs[0].Warning -EventName 'DataAdded' -Action { $records.Add('warning: ' + $Sender[$EventArgs.Index]) }.GetNewClosure() | Out-Null

Wait-Job $job | Out-Null

$records | Format-List
输出:

warning: warning1
information: information1
warning: warning2
information: information2
verbose: verbose1
information: information3
如前所述,我引用了错误的代码。这就是实际执行的内容:

// extract results and handle them
Collection<PSStreamObject> results = ReadAll<PSStreamObject>(job.Results);

if (_wait)
{
    foreach (var psStreamObject in results)
    {
        psStreamObject.WriteStreamObject(this, job.Results.SourceId);
    }
}
else
{
    foreach (var psStreamObject in results)
    {
        psStreamObject.WriteStreamObject(this);
    }
}
由于某些原因,
ObjectType=Verbose
不在集合中。我假设详细记录是从
MethodExecutor
记录中提取出来的。输出:

MethodExecutor
Warning Record: warning1
MethodExecutor
Information Record: information1
MethodExecutor
Warning Record: warning2
MethodExecutor
Information Record: information2
MethodExecutor
MethodExecutor
Information Record: information3
MethodExecutor
我找到了一个更好的方法,如何从工作中获得结果,但它只适用于新创造的工作。下面的代码为集合上的DataAdded事件添加事件处理程序:

$job = Start-Job -ScriptBlock $sb

$records = New-Object 'System.Collections.Generic.List[System.String]'

Register-ObjectEvent -InputObject $job.ChildJobs[0].Verbose -EventName 'DataAdded' -Action { $records.Add('verbose: ' + $Sender[$EventArgs.Index]) }.GetNewClosure() | Out-Null
Register-ObjectEvent -InputObject $job.ChildJobs[0].Information -EventName 'DataAdded' -Action { $records.Add('information: ' + $Sender[$EventArgs.Index]) }.GetNewClosure() | Out-Null
Register-ObjectEvent -InputObject $job.ChildJobs[0].Warning -EventName 'DataAdded' -Action { $records.Add('warning: ' + $Sender[$EventArgs.Index]) }.GetNewClosure() | Out-Null

Wait-Job $job | Out-Null

$records | Format-List
输出:

warning: warning1
information: information1
warning: warning2
information: information2
verbose: verbose1
information: information3

您引用了错误的代码部分。是实际使用的。单个集合=>相对顺序没有问题。据我所知,该集合无法从公共界面访问。您引用了错误的代码部分。是实际使用的。单个集合=>相对顺序没有问题。据我所知,这些藏品无法从公共场所进入。