1
\$\begingroup\$

I'm currently updating a ping script I maintain at work, transitioning from WinForms to WPF. Because of this I've started learning about and incorporating runspaces to keep the GUI responsive during heavy processing tasks. The code snippets below are inside of button click events. I'm wondering:

  1. Is this too much logic for a controller-level script?
  2. Should I break this up into functions?

There will be at least two runspaces tied to UI events, but each requires different function and variable injections, so I'm looking for best practices around structure and maintainability.

Any guidance, designing tips, or feedback would be greatly appreciated.

This code works, however, not outside of the context of my script. I was referred here from Stack Overflow because my question is opinion based.

Button Click 1 - Runspace #1

if ($script:syncHash.ButtonState -eq "First Click") {
 
 # Wait-Debugger
 # Get body of function
 $ssImportMasterDevice = Get-content Function:\Import-MasterDevice -ErrorAction Stop
 $ssUpdateDeviceIps = Get-Content Function:\Update-DeviceIPs -ErrorAction Stop
 
 #Create a sessionstate function entry
 $ssImportMasterDevice = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList 'Import-MasterDevice', $ssImportMasterDevice
 $ssUpdateDeviceIps = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList 'Update-DeviceIPs', $ssUpdateDeviceIps
 
 #Create a sessionstatefunction
 $InitialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault() 
 $InitialSessionState.Commands.Add($ssImportMasterDevice) 
 $InitialSessionState.Commands.Add($ssUpdateDeviceIps)
 $InitialSessionState.ImportPSModule($modulePath)
 # $initialSessionState.ExecutionPolicy = "Unrestricted"
 
 # Create the runspacepool by adding the sessionstate with the custom function
 $runspace = [runspacefactory]::CreateRunspace($InitialSessionState)
 $powershell = [powershell]::Create()
 $powershell.runspace = $runspace
 $runspace.Open()
 # $runspace.ThreadOptions = "ReuseThread" #Helps to prevent memory leaks, show runspace config in console
 
 # Wait-Debugger
 $runspace.SessionStateProxy.SetVariable("syncHash", $syncHash)
 $runspace.SessionStateProxy.SetVariable("syncHash2", $syncHash2)
 # Wait-Debugger
 $powershell.AddScript({
 # Wait-Debugger
 $syncHash2.masterDevices = Import-MasterDevice -path $syncHash2.masterPath -worksheet "LegacyIP-Store" 
 $synchash2.masterDevices = Update-DeviceIPs -Devices $synchash2.masterDevices -formDetails $synchash2.formDetails 
 
 $syncHash.txtBlkPing.Dispatcher.Invoke([action] {
 $syncHash.txtBlkPing.text = "Ready to ping devices. Please click 'PING'." 
 })
 
 $syncHash.btnPing.Dispatcher.Invoke([action] {
 $syncHash.btnPing.Content = "PING"
 $syncHash.ButtonState = "Second Click"
 })
 # Wait-Debugger
 
 })
 $script:asyncObject = $powerShell.BeginInvoke()
 
 }

Button Click 2 - Runspace #2 (so far)

elseif ($script:syncHash.ButtonState -eq "Second Click") {
 # Wait-Debugger
 ## Load RunspacePing function into SessionState object for injection into runspace
 $ssRunspacePing = Get-Content Function:\RunSpacePing -ErrorAction Stop
 $ssRunspacePing = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList 'RunspacePing', $ssRunspacePing
 
 ## Add function to session state
 $initialSessionState2 = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
 $InitialSessionState2.Commands.Add($ssRunspacePing)
 $InitialSessionState2.ExecutionPolicy = "Unrestricted"
 $runspace = [runspacefactory]::CreateRunspace($InitialSessionState2)
 $powershell = [powershell]::Create()
 $powershell.runspace = $runspace
 $runspace.ThreadOptions = "ReuseThread" #Helps to prevent memory leaks, show runspace config in console
 $runspace.ApartmentState = "STA" #Needs to be in STA mode for WPF to work
 $runspace.Open()
 $runspace.SessionStateProxy.SetVariable('syncHash', $synchash)
 $runspace.SessionStateProxy.SetVariable('syncHash2', $synchash2)
 $runspace.SessionStateProxy.SetVariable('synchash3', $synchash3)
 [void]$powershell.AddScript({
 $script:synchash3.pingResults = RunSpacePing -pingTable $syncHash2.masterDevices -syncHash $synchash
 $script:syncHash.MainWindow.Dispatcher.Invoke([action] {
 $script:syncHash.MainWindow.Close()
 })
 })
 $script:asyncObject2 = $powershell.BeginInvoke()
 }
toolic
14.2k5 gold badges29 silver badges200 bronze badges
asked Jun 14 at 14:47
\$\endgroup\$

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.