Supporting Synchronized Collections in PoshRSJob

I had a question where someone asked if PoshRSJob had support for synchronized variables (or collections) much like I have shown in the past using runspaces. This happened to be something that I touted as an advantage over the use of PSJobs and it would only make sense that you can do this using PoshRSJob as its backend framework is based on the use of runspaces and runspacepools.

Utilizing a synchronized collection for PoshRSJob really isn’t any different than what I have shown in the past. The first thing that we have to do is set up the synchronized collection that will be used to hold all of our variables and values.

$SyncHashTable = [hashtable]::Synchronized(@{})

Now I am going to add a single item to it just for reference.

$SyncHashTable.Initial = $True

We can build a small scriptblock that will be used to add some stuff to this hashtable so it is available in the other runspaces as well. We also need to ensure that the hashtable is locked at the syncroot property. Note that we are using the Enter and Exit methods in System.Threading.Monitor to accomplish this action and specifying the SyncRoot property of the hash table, not the hash table itself.

$ScriptBlock = {
    Param($SyncHash)

    [System.Threading.Monitor]::Enter($SyncHash.SyncRoot)
    $SyncHash["Job$($_)"] = [appdomain]::GetCurrentThreadId()
    Start-Sleep -Seconds (Get-Random (1..5))
    [System.Threading.Monitor]::Exit($SyncHash.SyncRoot)
}

In this case, I am going to list my job name as well as the thread id that is has. Since we are using runspacepools for PoshRSJob, it is set to reuse the runspace meaning that we should see the same thread ids and should have them even when I group the objects by value.

Next up is actually running the RSjobs and wait for everything to finish up.

1..10|Start-RSjob -Name {$_} -ScriptBlock $ScriptBlock -ArgumentList $SyncHashTable | 
Wait-RSJob –ShowProgress
LockObject_PoshRSJob

First time using GifCam, its a work in progress 😉

Once that has completed, we can see if I was right about the thread ids.

$SyncHashTable.GetEnumerator()|Group-Object -Property Value

image

As predicted, since my default throttle in Start-RSJob is set to 5 and I had 10 RSJobs queued up, we have exactly 5 thread ids that are reused. And at the end of all of this is that my synchronized  hash table was locked prior to being updated using to ensure there is no race condition that would prevent this from not working.

With that we now know how to share synchronized collections across multiple RSJobs using the PoshRSJob module. Just make sure that you utilize the Enter and Exit methods mentioned earlier to avoid possible errors and possible data loss.

This entry was posted in powershell and tagged , , , . Bookmark the permalink.

Leave a comment