title: PowerShell: Runspace & Delegates
body: <p>I try to improve the speed of my Exchange Online script by using runspaces. My problem is the fact that the script-block could not call the <code>Get-MailboxFolderStatistics</code> because this cmdlet is provided by the Exchange Online module. </p>
  
  <p>Therefore have I tried to use an delegate, see following sample code. </p>
  
  <pre><code>function getData() {
      param(
          [Parameter(Mandatory)]
          [int]
          $Number,
  
          [Parameter(Mandatory)]
          [Func[int, System.Object]] 
          $func_GetMailboxFolderStatistics
      )
  
      $result = $func_GetMailboxFolderStatistics.Invoke($Number)
  
      "test -&gt; $result"
  }
  
  
  $runspacePool = [RunspaceFactory]::CreateRunspacePool(1, 20)
  
  $runspacePool.Open()
  
  $asyncJobs = @()
  $n = 0
  
  [Func[int, System.Object]] $func = { 
      param($num)  
      Start-Sleep 5
      "$num +++&gt; $num" 
  }
  
  
  0..3 | ForEach-Object {
  
      $thread = [powershell]::Create()
  
      [void]$thread.AddScript($function:getData)
      [void]$thread.AddArgument($_)
      [void]$thread.AddArgument($func)
      $thread.RunspacePool = $runspacePool
  
      $asyncJobs += New-Object PSObject -Property @{
          RunNum = $n
          Pipe = $thread
          Result = $thread.BeginInvoke()
      }
  
      $n++
  }
  
  
  do {
      Write-Host "." -NoNewline
      Start-Sleep -Seconds 1
   } 
   while ( $asyncJobs.Result.IsCompleted -contains $false )
  
   Write-Host "All jobs completed!"
  
  
   $outcome = foreach($job in $asyncJobs){ $job.Pipe.EndInvoke($job.Result) }
  
   $outcome
  </code></pre>
  
  <p>The idea is that i call <code>Get-MailboxFolderStatistics</code> inside my delegate. It actually works, but it seems like my code is executed in sync- instead of async-mode one i call <code>.Invoke</code> </p>