Weird error running Invoke-Parallel
Please, observe the following script:
param([switch]$Cleanup, [Switch]$MockMutex, $N = 1)
function Cleanup()
{
1..$N | ForEach-Object {
Unregister-PSRepository "r$_" -ErrorAction SilentlyContinue
}
Remove-Item $WorkDir -ErrorAction SilentlyContinue -Recurse
}
$WorkDir = "$env:TEMP\fb22c60e-a0c5-48b3-953a-0b580c6a2f5e"
if ($Cleanup)
{
Cleanup
}
else
{
if ($MockMutex)
{
class MutexMock
{
WaitOne() { }
ReleaseMutex() { }
}
$mtx = [MutexMock]::New()
}
else
{
$mtx = [Threading.Mutex]::New($false)
}
1..$N | Invoke-Parallel {
$RepositoryName = "r$_"
$WorkDir = $Using:WorkDir
$null = mkdir "$WorkDir\$RepositoryName" -Force -ErrorAction SilentlyContinue
$null = $parameter.WaitOne()
try
{
if (!(Get-PSRepository -Name $RepositoryName -ErrorAction SilentlyContinue))
{
Write-Host "[$([AppDomain]::GetCurrentThreadId())] BEGIN[$RepositoryName]"
Register-PSRepository $RepositoryName `
-SourceLocation "$WorkDir\$RepositoryName" `
-PublishLocation "$WorkDir\$RepositoryName" `
-InstallationPolicy Trusted
Write-Host "[$([AppDomain]::GetCurrentThreadId())] [$RepositoryName]END"
}
}
finally
{
$parameter.ReleaseMutex()
}
} -Parameter $mtx
Get-PSRepository | Where-Object { $_.Name.StartsWith('r') }
Cleanup
}
It just tries to run Register-PSRepository in parallel the given number of times. The default is to use a mutex to actually serialize the calls to the functions Get-PSRepository and Register-PSRepository (thus killing the parallelism, of course, but this is a different story). Passing -MockMutex switch replaces a real mutex object with a mock.
Strange things happen when calling with the mock and N greater than 1:
PS C:\> .\1.ps1 -MockMutex -N 2
Get-RunspaceData : A parameter cannot be found that matches parameter name 'Provider'.
At C:\misc\Invoke-Parallel.ps1:591 char:13
+ Get-RunspaceData -wait
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Write-Error], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Get-RunspaceData
[37616] BEGIN[r1]
[37616] [r1]END
Name InstallationPolicy SourceLocation
---- ------------------ --------------
r1 Trusted C:\Users\MKHARI~1\AppData\Local\Temp\fb22c60e-a0c5-48b3-953a-0b580c6a2f5e\r1
PS C:\>
All works fine when N = 1 or when called with a real mutex object.
The only explanation that I see is that the Get/Register-PSRepository functions are not multi-thread safe and calling them in parallel screws things up in such a way that it affects Invoke-Parallel somehow.