Мне нужно добавить возможности многопоточности в скрипт PowerShell. К сожалению, я получаю сообщение об ошибке при попытке открыть пул пространства выполнения с помощью пользовательских классов C # в объекте InitialSessionState
. В следующем примере приведен только код DEMO, а не оригинальный скрипт. Вы можете скопировать и вставить его, и он будет работать без каких-либо изменений, необходимых. Что действительно странно, так это то, что все, кажется, работает правильно, несмотря на сообщение об ошибке, возникающее при открытии пула пространства выполнения.
Это сообщение об ошибке (переведено):
Ошибка при загрузке файла данных расширенного типа: Ошибка в данных типа "FooBar.BarClass": TypeData должно иметь: "Members", "TypeConverters", "TypeAdapters" или "StandardMembers".
Я уже работал и тестировал в течение нескольких часов и понятия не имею, в чем причина этого сообщения. И да, я знаю, что есть очень хорошие библиотеки и командлеты, доступные для многопоточности, но я не могу использовать их по разным причинам.
# Simple c-sharp classes
Add-Type -TypeDef @"
namespace FooBar {
public class FooClass {
public string Foo() {
return "Foo";
}
}
public class BarClass {
public string Bar() {
return "Bar";
}
}
}
"@
function callFooBar {
[FooBar.FooClass]$foo = New-Object FooBar.FooClass
[FooBar.BarClass]$bar = New-Object FooBar.BarClass
$foo.Foo() + $bar.Bar()
}
$scriptBlock = {
Write-Output ( callFooBar )
}
# Setting up an initial session state object
$initialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
# Getting the function definition for the functions to add
$functionDefinition = Get-Content function:\callFooBar
$functionEntry = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList 'callFooBar', $functionDefinition
# And add it to the iss object
[void]$initialSessionState.Commands.Add($functionEntry)
# Get the type data for the custom types to add
$typeData = New-Object System.Management.Automation.Runspaces.TypeData -ArgumentList 'FooBar.FooClass'
$typeEntry = New-Object System.Management.Automation.Runspaces.SessionStateTypeEntry -ArgumentList $typeData, $false
# And add it to the iss object
[void]$initialSessionState.Types.Add($typeEntry)
# Get the type data for the custom types to add
$typeData = New-Object System.Management.Automation.Runspaces.TypeData -ArgumentList 'FooBar.BarClass'
$typeEntry = New-Object System.Management.Automation.Runspaces.SessionStateTypeEntry -ArgumentList $typeData, $false
# And add it to the iss object
[void]$initialSessionState.Types.Add($typeEntry)
# Create Runspace pool
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, ([int]$env:NUMBER_OF_PROCESSORS + 1), $initialSessionState, $Host)
$RunspacePool.ApartmentState = 'MTA'
[void]$RunspacePool.Open() # <<<< Error occurs here!
[System.Collections.Generic.List[object]]$Jobs = @()
1..2 | % {
$job = [System.Management.Automation.PowerShell]::Create($initialSessionState)
$job.RunspacePool = $RunspacePool
[void]$job.AddScript($scriptBlock)
$jobs += New-Object PSObject -Property @{
RunNum = $_
Pipe = $job
Result = $job.BeginInvoke()
}
}
do {
} while ($jobs.Result.IsCompleted -contains $false)
Write-Host "All jobs completed!"
$Results = @()
foreach ($job in $jobs) {
$Results += $job.Pipe.EndInvoke($job.Result)
}
$Results
$RunspacePool.Close()
$RunspacePool.Dispose()