Skip to content

Instantly share code, notes, and snippets.

@urasandesu
Created March 4, 2013 13:41
Show Gist options
  • Save urasandesu/5082301 to your computer and use it in GitHub Desktop.
Save urasandesu/5082301 to your computer and use it in GitHub Desktop.
$script = {
($InputObject, $2to1Ready, $1to2Ready, $2to1End, $1to2End) = $($input)
$InputObject_ = $InputObject.GetNewClosure()
try {
do {
& $InputObject_ |
ForEach-Object {
$_
[Void]$2to1Ready.Set()
[Void]$1to2Ready.WaitOne()
if ($1to2End.WaitOne(0)) {
break
}
}
} until ($true)
} finally {
[Void]$2to1End.Set()
do {
[Void]$2to1Ready.Set()
} until ($1to2End.WaitOne(1))
}
}
$runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
try {
$runspace.Open()
$pipeline = $runspace.CreatePipeline($script)
[Void]$pipeline.Input.Write({ 11..20 })
$2to1Ready = New-Object Threading.AutoResetEvent $false
[Void]$pipeline.Input.Write($2to1Ready)
$1to2Ready = New-Object Threading.AutoResetEvent $false
[Void]$pipeline.Input.Write($1to2Ready)
$2to1End = New-Object Threading.ManualResetEvent $false
[Void]$pipeline.Input.Write($2to1End)
$1to2End = New-Object Threading.ManualResetEvent $false
[Void]$pipeline.Input.Write($1to2End)
$pipeline.Input.Close()
$pipeline.InvokeAsync()
try {
do {
& { 1..10 } |
ForEach-Object {
[Void]$2to1Ready.WaitOne()
if ($2to1End.WaitOne(0)) {
break
}
if (!$pipeline.Output.EndOfPipeline) {
($_, ($pipeline.Output.NonBlockingRead() | % { $_ })) -join ', '
}
[Void]$1to2Ready.Set()
}
} until ($true)
} finally {
[Void]$1to2End.Set()
do {
[Void]$1to2Ready.Set()
} until ($2to1End.WaitOne(1) -and $pipeline.PipelineStateInfo.State -ne [Management.Automation.Runspaces.PipelineState]::Running)
if ($pipeline.PipelineStateInfo.State -eq [Management.Automation.Runspaces.PipelineState]::Failed) {
Write-Error -Exception $pipeline.PipelineStateInfo.Reason
}
$pipeline.Dispose()
}
} finally {
if ($null -ne $runspace) {
$runspace.Dispose()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment