Set-Resource and Get-Resource don't seem to work with an instance of System.Collections.Queue

Jun 25, 2011 at 2:47 PM


I'd like to store a queue in the resources dictionary , and it seems that Set/Get Resources won't work with a queue instance. This may be a syntax error on my part? Workaround is to store/retrieve the queue instance directly from the Resources dictionary.  In the code below, only the first example works.

ipmo showui

new-label {
"hello"
} -on_loaded {
$queue = [System.Collections.Queue]::Synchronized( (New-Object System.Collections.Queue) )
write-debug ("in window Loaded handler, queue.count is {0}, type is {1} "`
  -f $queue.count, $queue.GetType())

$window.Resources.queue_works = $queue
write-debug ("in window Loaded handler, queue_works.count is {0}, type is {1} "`
  -f $window.Resources.queue_works.count, $window.Resources.queue_works.GetType())

Set-Resource -Visual $window -Name queue -Value $queue
$q2 = get-Resource -Visual $window -Name queue
write-debug ("in window Loaded handler, q2.count is {0} " -f $q2.count)

Set-Resource -Visual $window -Name queue -Value ($queue)
$q2 = get-Resource -Visual $window -Name queue
write-debug ("in window Loaded handler, q2.count is {0} " -f $q2.count)

Set-Resource -Visual $window -Name queue -Value [ref]$queue
$q2 = get-Resource -Visual $window -Name queue
write-debug ("in window Loaded handler, q2.count is {0} " -f $q2.count)

Set-Resource -Visual $window -Name queue -Value ([ref]$queue)
$q2 = get-Resource -Visual $window -Name queue
write-debug ("in window Loaded handler, q2.count is {0} " -f $q2.count)

Set-Resource -Visual $window -Name queue -Value "$queue"
$q2 = get-Resource -Visual $window -Name queue
write-debug ("in window Loaded handler, q2.count is {0} " -f $q2.count)

$q2 = get-Resource -Visual $window -Name queue_works
write-debug ("in window Loaded handler, getting queue_works doesn't work either, q2.count is {0} " -f $q2.count)

}- show

Coordinator
Jun 26, 2011 at 8:23 PM

The problem here is that you're over setting the resource.

The queue is indeed set to something, until it goes thru Set-Resource to be reset.

The Set-Resource puts in an empty collection.

You get back an empty collection from Get-Resource

PowerShell unrolls an empty collection on the way out of a function.

You actually don't need to constantly be setting the resource though.

ShowUi also contains automatic variables for resources, so once queue is in the resources, you can refer to it in other event handlers.  Because of the way that overload gets information, you won't have to worry if queue is empty.

 

 

 

Jun 28, 2011 at 2:41 PM

Umm, I don't understand your response. I am creating an instance of System.Collections.Queue and assigning it to $queue, then loading it into $window.Resources.queue_works, and showing the count property is present on that object, to show that the $queue can be successfully stored in $window.Resources.

Then I try to load $queue into .Resources using Set-Resource, and I try to retrieve it into $q2.  This doesn't work, so I try 4 different syntaxs to Set-Resource into .Resources.queue, and after each, try to retrieve it into $q2. I'm only "constantly be setting the resource" because I'm trying different syntax to make it work.

My understanding of Set-Resource may be flawed, but from studying the code, it seems that Set-Resource should take the System.Collections.Queue instance stored in $queue, and put it into $visual.Resources.Queue (wehre $visual is $window in my examples above). And Get-Resource should take whatever object is stored in $visual.Resources.Queue, and assign it to whatever is on the left-hand-side of the "=".

I'm having no problem using Set/Get-Resource for function parameters, for strings, or for scriptblocks, but for some reason, I can't get Set-Resource to store an instance of System.Collections.Queue.

 

 

Jul 7, 2011 at 4:03 AM

I tested it again with the July 6 drop - still same behaviour. I simplified the issue even further, this little following program clearly demonstrates the issue. I posted a similar problem over on powershellcommunity.org: "Why do these functions return a runtime object, not a queue?" [http://www.powershellcommunity.org/Forums/tabid/54/aft/6865/Default.aspx], demonstrating that instances of Collections.Queues and instances of MSMQueue MessageQueues cannot be returned from functions. The response there was to "return the queue wrapped in an array", that is, the last statement of the function should be ,$lclqueue because "Powershell is flattening the object when it returns from the function". I'm still trying to learn what's going on, but looking at Get-Resource, I bet it is "flattening the Queue object" when returning it.   If I figure out why Powershell is "flatening the object", I'll update this discussion. You mentioned that Powershell is unrolling an empty collection - does this mean that an instance of a Queue, if it has no messages in it, gets returned as "nothing"? If so - we should never use "get-Resource" on a collection object if that collection object could possibly be empty? because we won't be handed the actual collection unless it has something in it?

new-label {
"hello"
} -on_loaded {
$queue = [System.Collections.Queue]::Synchronized( (New-Object System.Collections.Queue) )

# Use Set-Resource to store the queue in the Resource dictionary
Set-Resource -Visual $window -Name queue -Value $queue

# This proves the "Set-Resource" worked
write-debug ("in window Loaded handler, `$window.Resources.queue.count is {0}, type is {1} "`
  -f $window.Resources.queue.count, $window.Resources.queue.GetType())

# This "Get-Resource" does not work
$q2 = get-Resource -Visual $window -Name queue
write-debug ("in window Loaded handler, q2.count is {0} " -f $q2.count)

}-show