Digger
Digger

Reputation: 87

Powershell synchronized hash table thread safety

I have a WPF script running into problems recently.

The script does subnet scanning using PSParallel module. When the subnet CIDR is less than 21, it starts having the problem.

The problem is: I have a concurrent queue as a member of a synchronized hash table. The queue is used for producer/consumer model. The scanning threads keep enqueue the data and the GUI thread keep dequeue data and write it to a richtextbox. The dequeue process is handled by a dispatch timer event handler, which is executed every 20 ms. When the CIDR >=21, there is no problem. But when CIDR <21, sometimes it will throw an error message:

Collection was modified; enumeration operation may not execute.
At E:\PSScanner\PSScanner.ps1:446 char:8
+     if($syncHash.Q.Count -ne 0){
+        ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], InvalidOperationException
    + FullyQualifiedErrorId : System.InvalidOperationException

I think the synchronized hash table is thread safe and the concurrent queue is thread safe as well. Not sure why is this happening.

The source code is here: https://github.com/MeCRO-DEV/PSScanner

Upvotes: 3

Views: 1284

Answers (1)

Digger
Digger

Reputation: 87

I fixed the problem eventually.

I was calling a scriptblock stored in a synchronized hash table: $syncHash.Output, which send the output string to a concurrent queue. That scriptblock causes the output messed up and the worker threads terminated unexpectedly. After enqueue the data directly, instead of calling the scriptblock, problem solved.

Also, I have an IP counter $syncHash.Count. I thought it should be thread-safe as it is stored in the synchronized hash table, but actually it is not. I was getting inaccurate counts every time. After setting up a mutex to protect the counter variable, it works perfectly. The only reason I was thinking is the counter is updated in worker threads which are PSParallel instances(Invoke-Parallel cmdlet). Not sure how it handles the hash table.

Thank you all for your help.

Upvotes: 1

Related Questions