Multithreading & Syncronized Hashtable

Synchronized Hashtable

Multi-threading with Runspaces 

http://cjoprey.blog.com/2009/08/17/asynchronicity-in-powershell/

http://newsqlblog.com/2012/05/22/concurrency-in-powershell-multi-threading-with-runspaces/

This example did not work for me, but I need to spend more time on it.

http://learn-powershell.net/2012/10/14/powershell-and-wpf-writing-data-to-a-ui-from-a-different-runspace/

$newPowerShell = [PowerShell]::Create() $newPowerShell | gm $newPowerShell.InvocationStateInfo | gm $newPowerShell.InvocationStateInfo.State

Short version of code from Powershell Studio 2012

$form1_Load={     #TODO: Initialize Form Controls here     $sharedData = [HashTable]::Synchronized(@{})     $sharedData.Foo = "bar"     $sharedData.Status = "running"     $Textbox1.Text = $sharedData.Foo     $newRunspace = [RunSpaceFactory]::CreateRunspace()     $newRunspace.ApartmentState = "STA"     $newRunspace.ThreadOptions = "ReuseThread"     $newRunspace.Open()     $newRunspace.SessionStateProxy.setVariable("sharedData", $sharedData)     $newPowerShell = [PowerShell]::Create()     $newPowerShell.Runspace = $newRunspace }  $buttonSingleClick_Click={     $this.Enabled = $False     #TODO: Place custom script here     $newPowerShell.AddScript({$sharedData.Foo = "fred"; sleep 5; $sharedData.Foo = "ddddd"; sleep 5; $sharedData.Status = "done"}).BeginInvoke()      #Change while statement to check $newPowerShell.InvocationStateInfo.State     while ($sharedData.Status -ne "done" )     {         #Write-Host $sharedData.Foo $sharedData.Status         $Textbox1.AppendText($sharedData.Foo + "`r`n")     }               #Process the pending messages before enabling the button     [System.Windows.Forms.Application]::DoEvents()     $this.Enabled = $True }

Long version of code from Powershell Studio 2012

Have not done this yet but evidently you can use the entire textbox inside the sycronized hashtable

$sharedData.Foo = [System.Windows.Forms.TextBox]$textbox1

Global Variables: $SharedVariable = [HashTable]::Synchronized(@{}) $NewPowerShell = $null Function AddTextboxToSharedVariable() {     $SharedVariable.Add("OutputTB",[System.Windows.Forms.RichTextBox]$OutputRichTB) } Function NewPowershellSession() {     $NewRunspace = [RunSpaceFactory]::CreateRunspace()     $NewRunspace.ApartmentState = "STA"     $NewRunspace.ThreadOptions = "ReuseThread"     $NewRunspace.Open()     $NewRunspace.SessionStateProxy.SetVariable("SharedVariable", $SharedVariable)     $NewPowerShell = [PowerShell]::Create()     $NewPowerShell.Runspace = $NewRunspace     return $NewPowerShell } Function DisposeOldPowershellSession() { If ($NewPowerShell -ne $null) { $NewPowerShell.Runspace.Dispose() $NewPowerShell.Runspace = $null $NewPowerShell.Dispose() $NewPowerShell = $null } Function within main Thread invoking the Second Thread: Function Main() { AddTextboxToSharedVariable $ScriptBlock ={ Param ($User) Import-Module "C:\temp\MyFunctions.psm1"  Get-USERGROUPSFROMAD $User $SharedVariable.OutputTB } DisposeOldPowershellSession $NewPowerShell = NewPowershellSession $NewPowerShell.AddScript($ScriptBlock) $NewPowerShell.AddParameter("User", $User) $Job = $NewPowerShell.BeginInvoke() }

blah blah

#------------------------------------------------------------------------ # Source File Information (DO NOT MODIFY) # Source ID: 9e3e6853-1b6a-4db1-af00-67e02dcdd5ea # Source File: C:\Users\currank\Documents\SAPIEN\PowerShell Studio 2012\Files\blah.pff #------------------------------------------------------------------------ #region File Recovery Data (DO NOT MODIFY) <#RecoveryData: IA8AAB+LCAAAAAAABADsvQdgHEmWJSYvbcp7f0r1StfgdKEIgGATJNiQQBDswYjN5pLsHWlHIymr KoHKZVZlXWYWQMztnbz33nvvvffee++997o7nU4n99//P1xmZAFs9s5K2smeIYCqyB8/fnwfPyIe v8qn1WVeXz/N2uzoN07S9PGXdXFRLLPyWVHmL7JFfjQps/l4dX7++G7vK34Bf/1kXjdFtTzaHe89 vut/ICAnP51P27S9XuWfffT6umnzxfi7xXJWXTXjZ1W9kH9HaeyrUaqgPtsf7+C/UXqyLtt1nX+2 zNdtnZWj9OV6UhbT3yu/flO9zZefTR48yO5P73+6+/Defr5z8PCjdEnIfvbROcHb/SidzotyVlO7 j06qZVtXZfMRo0mIvqyrVV631/rCSVnky/Z18YP8o6P9h7uj9P7u/uO7ptHASyDMR0fc141t3+Tv 2o+OMM5+09NL6lvbPa+ymcL8/fH747v8rWl6M33R0ZPq3c86iVvqZ1K920jlPhmeV9Ospf4/Onpw f5Tu3j/oUaP/zheEYVEWS6L1m3qd3+INmRiD4S1ekInf+5Qmfm/n4S1eeJNNzpaz/B291J/PuzJL t5+zJ+u2rZY/61M24W5eF8uLMieGn779unN37+DhbSdPpqLX8y3elDkBm+zdu0VzNyO3mXARR0Eo vS1GXzX5TxbNOitft9dl/iSbvj2pyqoeZktfsIXgfUr8/tp7IOY+B4V/HDdNvqDZzhvTVj+5PlLu +SJbZhf5gqCNj9dtteA5c1y0e1suurc7Ob93cP/TbHbv0/383v3Hd21P3Z4XzbSqy2LyDfDqhl5k fN9AHz9z8uj3VRn7fb8opnXVVOft+MXpm9/3WU1zdVXVb3/fS0C/t3Nv9+Hvq3SdleWNyH3jovv1 UA21y60Qh1fwc4YvOr8lmnV2RbLzdTDduXd+//zB+e7u7P5Odi/7mphK/7dD9vdelF8H0W+EpL/3 F89vh+TToiblUtXXr/P6spjmX4trvxnadjG53QBOqjr/Ojh/I2RG57dDUwdFRoJG9nNH5BCNCOr2 T2NiHr8kQ0cWpTYj+zxf5oSgZyalgY0TxIRFP9UPz6YaMARNw0/JjhXnedOe1DmbMNj13me29cm6 IVtnvvdgD33xssxauNlH2/AXzB/261fr5es3x0c7j+/qb8Yyh6N//DqfruuCXIS75hM/HuIPwqiJ Z7sfOQlOdTVbT9te487n3fZdwsc+fZo307pYhUS7G/30pFqssqXnxtztfXJSra4pQpwHhO5/drZs 85qiyA6C8Y+jIae8MPwVYbZwfpPi6n3y+G4QnhpOAy/TzPoR8f8TAAD//ze2pC0gDwAA#> #endregion #======================================================================== # Code Generated By: SAPIEN Technologies, Inc., PowerShell Studio 2012 v3.0.8 # Generated On: 24/10/2012 3:38 p.m. # Generated By: currank #======================================================================== #---------------------------------------------- #region Application Functions #----------------------------------------------  function OnApplicationLoad {     #Note: This function is not called in Projects     #Note: This function runs before the form is created     #Note: To get the script directory in the Packager use: Split-Path $hostinvocation.MyCommand.path     #Note: To get the console output in the Packager (Windows Mode) use: $ConsoleOutput (Type: System.Collections.ArrayList)     #Important: Form controls cannot be accessed in this function     #TODO: Add snapins and custom code to validate the application load          return $true #return true for success or false for failure }  function OnApplicationExit {     #Note: This function is not called in Projects     #Note: This function runs after the form is closed     #TODO: Add custom code to clean up and unload snapins when the application exits          $script:ExitCode = 0 #Set the exit code for the Packager }  #endregion Application Functions  #---------------------------------------------- # Generated Form Function #---------------------------------------------- function Call-blah_pff {      #----------------------------------------------     #region Import the Assemblies     #----------------------------------------------     [void][reflection.assembly]::Load("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")     [void][reflection.assembly]::Load("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")     [void][reflection.assembly]::Load("System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")     [void][reflection.assembly]::Load("System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")     [void][reflection.assembly]::Load("System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")     [void][reflection.assembly]::Load("System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")     [void][reflection.assembly]::Load("System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")     [void][reflection.assembly]::Load("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")     [void][reflection.assembly]::Load("System.ServiceProcess, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")     #endregion Import Assemblies      #----------------------------------------------     #region Generated Form Objects     #----------------------------------------------     [System.Windows.Forms.Application]::EnableVisualStyles()     $form1 = New-Object 'System.Windows.Forms.Form'     $textbox1 = New-Object 'System.Windows.Forms.TextBox'     $buttonSingleClick = New-Object 'System.Windows.Forms.Button'     $InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState'     #endregion Generated Form Objects      #----------------------------------------------     # User Generated Script     #----------------------------------------------                                        $form1_Load={         #TODO: Initialize Form Controls here         $sharedData = [HashTable]::Synchronized(@{})         $sharedData.Foo = "bar"         $sharedData.Status = "running"         $Textbox1.Text = $sharedData.Foo         $newRunspace = [RunSpaceFactory]::CreateRunspace()         $newRunspace.ApartmentState = "STA"         $newRunspace.ThreadOptions = "ReuseThread"         $newRunspace.Open()         $newRunspace.SessionStateProxy.setVariable("sharedData", $sharedData)         $newPowerShell = [PowerShell]::Create()         $newPowerShell.Runspace = $newRunspace     }          $buttonSingleClick_Click={         $this.Enabled = $False         #TODO: Place custom script here         $newPowerShell.AddScript({$sharedData.Foo = "fred"; sleep 5; $sharedData.Foo = "ddddd"; sleep 5; $sharedData.Status = "done"}).BeginInvoke()              while ($sharedData.Status -ne "done" )         {             #Write-Host $sharedData.Foo $sharedData.Status             $Textbox1.AppendText($sharedData.Foo + "`r`n")         }                           #Process the pending messages before enabling the button         [System.Windows.Forms.Application]::DoEvents()         $this.Enabled = $True     }          # --End User Generated Script--     #----------------------------------------------     #region Generated Events     #----------------------------------------------          $Form_StateCorrection_Load=     {         #Correct the initial state of the form to prevent the .Net maximized form issue         $form1.WindowState = $InitialFormWindowState     }          $Form_Cleanup_FormClosed=     {         #Remove all event handlers from the controls         try         {             $buttonSingleClick.remove_Click($buttonSingleClick_Click)             $form1.remove_Load($form1_Load)             $form1.remove_Load($Form_StateCorrection_Load)             $form1.remove_FormClosed($Form_Cleanup_FormClosed)         }         catch [Exception]         { }     }     #endregion Generated Events      #----------------------------------------------     #region Generated Form Code     #----------------------------------------------     #     # form1     #     $form1.Controls.Add($textbox1)     $form1.Controls.Add($buttonSingleClick)     $form1.ClientSize = '491, 514'     $form1.Name = "form1"     $form1.Text = "Form"     $form1.add_Load($form1_Load)     #     # textbox1     #     $textbox1.Location = '75, 158'     $textbox1.Multiline = $True     $textbox1.Name = "textbox1"     $textbox1.Size = '261, 209'     $textbox1.TabIndex = 2     #     # buttonSingleClick     #     $buttonSingleClick.Location = '389, 158'     $buttonSingleClick.Name = "buttonSingleClick"     $buttonSingleClick.Size = '75, 23'     $buttonSingleClick.TabIndex = 1     $buttonSingleClick.Text = "Single Click"     $buttonSingleClick.UseVisualStyleBackColor = $True     $buttonSingleClick.add_Click($buttonSingleClick_Click)     #endregion Generated Form Code      #----------------------------------------------      #Save the initial state of the form     $InitialFormWindowState = $form1.WindowState     #Init the OnLoad event to correct the initial state of the form     $form1.add_Load($Form_StateCorrection_Load)     #Clean up the control events     $form1.add_FormClosed($Form_Cleanup_FormClosed)     #Show the Form     return $form1.ShowDialog()  } #End Function  #Call OnApplicationLoad to initialize if((OnApplicationLoad) -eq $true) {     #Call the form     Call-blah_pff | Out-Null     #Perform cleanup     OnApplicationExit }