Synchronized Hashtable with PoshRSJob

This topic contains 2 replies, has 2 voices, and was last updated by  Max Kozlov 2 months, 3 weeks ago.

  • Author
    Posts
  • #71740

    Peter
    Participant

    Hey guys,

    Been struggling to get my head round this for a few weeks now so I'm finally giving in and asking for help!

    I'm creating a GUI using WPF, formatted as XML, and I'm trying to use PoshRSJob for backgrounding tasks, etc, with a Synchronized Hashtable to share data between runspaces...

    I'm struggling to understand how I need to format things – I'll show you what I have so far.

    I have this to load the App.xaml file generated by Visual Studio and I'm fairly sure this is OK:

    function Get-XamlObject
    {
    	[CmdletBinding()]
    	param (
    		[Parameter(Position = 0,
    				   Mandatory = $true,
    				   ValuefromPipelineByPropertyName = $true,
    				   ValuefromPipeline = $true)]
    		[Alias("FullName")]
    		[System.String[]]$Path
    	)
    
    	BEGIN
    	{
    		Set-StrictMode -Version Latest
    
    		$wpfObjects = @{ }
    		Add-Type -AssemblyName presentationframework, presentationcore
    
    	} #BEGIN
    
    	PROCESS
    	{
    		try
    		{
    			foreach ($xamlFile in $Path)
    			{
    				#Change content of Xaml file to be a set of powershell GUI objects
    				$inputXML = Get-Content -Path $xamlFile -ErrorAction Stop
    				$inputXMLClean = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace 'x:Class=".*?"', '' -replace 'd:DesignHeight="\d*?"', '' -replace 'd:DesignWidth="\d*?"', ''
    				[xml]$xaml = $inputXMLClean
    				$reader = New-Object System.Xml.XmlNodeReader $xaml -ErrorAction Stop
    				$tempform = [Windows.Markup.XamlReader]::Load($reader)
    
    				#Grab named objects from tree and put in a flat structure
    				$namedNodes = $xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]")
    				$namedNodes | ForEach-Object {
    
    					$wpfObjects.Add($_.Name, $tempform.FindName($_.Name))
    
    				} #foreach-object
    			} #foreach xamlpath
    		} #try
    		catch
    		{
    			throw $error[0]
    		} #catch
    	} #PROCESS
    
    	END
    	{
    		Write-Output $wpfObjects
    	} #END
    }
    
    $path = '*path to folder containing xaml files*'
    

    This is where I'm not so sure... I'll comment the code with what I'm trying to do with each section – hoping someone can tell me where I'm going wrong!

    #creating the hashtable
    $SyncHash = [hashtable]::Synchronized(@{})
    
    #adding the xaml code to the hashtable just created
    $syncHash.wpf = Get-ChildItem -Path $path -Filter *.xaml -file | Where-Object { $_.Name -ne 'App.xaml' } | Get-XamlObject
    
    #scriptblock for RSJob (not really understanding what needs to be put in here and what doesn't)
    $ScriptBlock = {
        Param($SyncHash)
        #something to do with setting the hashtable to the syncroot properly (?)
        [System.Threading.Monitor]::Enter($SyncHash.SyncRoot)
    
        [pscustomobject] @{
    
    #I have various functions like this to show different pages, calculate things, etc, this is just an example of the kind of thing that they do
    function Get-Results {
        $script:syncHash.home_Grid.Visibility = 'Collapsed'
        $script:syncHash.processing_Grid.Visibility = 'Collapsed'
        $script:syncHash.results_Grid.Visibility = 'Visible'
    }
    
    function Update-ProgressBar {
        while ($script:syncHash.displayThreatLevel -lt $script:syncHash.threatLevel) {
            Write-Output $script:syncHash.displayThreatLevel $script:syncHash.threatLevel
            $script:syncHash.displayThreatLevel += 1
            Start-Sleep -Milliseconds 100
            Display-ThreatLevel
        }
    }
    
        $SyncHash.Email_Check.ShowDialog() | Out-Null
    
        [System.Threading.Monitor]::Exit($SyncHash.SyncRoot)
        }
    }
    
    Start-RSJob -Name {$_} -ScriptBlock $ScriptBlock -ArgumentList $wpf -FunctionsToLoad Get-Home |
    Wait-RSJob -ShowProgress
    
  • #71770

    Max Kozlov
    Participant

    Here is my test

    During operation, the UI responsiveness leaves much to be desired due to Dispatcher.Invoke()
    🙁

    may be callbacks should be implemented through System.Windows.Threading.DispatcherTimer

  • #71773

    Max Kozlov
    Participant

    anyway, you should dig https://learn-powershell.net/ 🙂

You must be logged in to reply to this topic.