Do Jobs really work in background in powershell? -


i trying implement background commands initiate after user clicks button, , far have ended ui locking while job on-going. using time consuming loop check if ui locks up. can let job work in background ui freed up. not sure want complicate code adding runspaces. doing incorrectly?

$inputxml = @" <window x:class="wpfapplication2.mainwindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"         xmlns:local="clr-namespace:wpfapplication2"         mc:ignorable="d"         title="create user" height="448.05" width="656.017" resizemode="noresize">     <grid margin="0,0,-6.8,-0.8" background="#ffd7d7d7">         <grid.rowdefinitions>             <rowdefinition height="403*"/>             <rowdefinition height="18*"/>         </grid.rowdefinitions>         <grid.columndefinitions>             <columndefinition/>         </grid.columndefinitions>         <button x:name="create_user" content="create user" horizontalalignment="left" margin="67,224,0,0" verticalalignment="top" width="300" height="26" rendertransformorigin="0.551,-0.671" isenabled="true">             <button.background>                 <lineargradientbrush endpoint="0,1" startpoint="0,0">                     <gradientstop color="#fff3f3f3" offset="0"/>                     <gradientstop color="#ffebebeb" offset="0.5"/>                     <gradientstop color="#ffdddddd" offset="0.5"/>                     <gradientstop color="#ffcdcdcd" offset="1"/>                 </lineargradientbrush>             </button.background>         </button>         <label x:name="fname" content="" horizontalalignment="left" margin="43,11,0,0" verticalalignment="top" height="26" width="10"/>         <label x:name="fname1" content="first name" horizontalalignment="left" margin="88,54,0,0" verticalalignment="top" width="72" rendertransformorigin="0.513,1.469" height="26"/>         <label x:name="lname" content="last name" horizontalalignment="left" margin="88,83,0,0" verticalalignment="top" rendertransformorigin="-0.167,-0.458" width="72" height="25"/>         <textbox x:name="fnametxt" height="23" margin="167,54,0,0" textwrapping="wrap" verticalalignment="top" rendertransformorigin="0.501,0.452" horizontalalignment="left" width="136"/>         <button x:name="exitbtn" content="exit" horizontalalignment="left" verticalalignment="top" width="135" margin="447,365,0,0" height="38" rendertransformorigin="0.489,0.462"/>         <label x:name="label" content="password" horizontalalignment="left" margin="92,113,0,0" verticalalignment="top" rendertransformorigin="0.064,0.601" height="26" width="68"/>         <passwordbox x:name="passwordbox" margin="167,113,0,0" verticalalignment="top" height="24" horizontalalignment="left" width="136"/>         <textbox x:name="stsbox" horizontalalignment="left" height="62" margin="67,267,0,0" textwrapping="wrap" verticalalignment="top" width="300" background="#ffdadada" foreground="black" opacity="0.45" selectionbrush="#ff1d6ebf" rendertransformorigin="0.503,-0.59" isreadonly="true"/>         <textbox x:name="lnametxt" height="23" margin="167,85,0,0" textwrapping="wrap" verticalalignment="top" horizontalalignment="left" width="136"/>     </grid> </window> "@   $inputxml = $inputxml -replace 'mc:ignorable="d"','' -replace "x:n",'n'  -replace '^<win.*', '<window' [void][system.reflection.assembly]::loadwithpartialname('presentationframework') [void][system.reflection.assembly]::loadwithpartialname("system.windows.forms") [xml]$xaml = $inputxml  #read xaml $reader=(new-object system.xml.xmlnodereader $xaml)  try{$form=[windows.markup.xamlreader]::load( $reader )} catch{write-host "unable load windows.markup.xamlreader. double-check syntax , ensure .net installed."} $xaml.selectnodes("//*[@name]") | %{set-variable -name "wpf$($_.name)" -value $form.findname($_.name) -scope global}   function global:get-formvariables{ if ($global:readmedisplay -ne $true) {$global:readmedisplay=$true} #write-host "found following interactable elements our form" -foregroundcolor cyan get-variable wpf* }    get-formvariables    $wpfcreate_user.add_click({  $test = { for($i=1; $i -le 100000; $i++){ $z = $i + $z $z }}  $job = start-job $test  wait-job $job  receive-job $job -outvariable results remove-job $job $wpfstsbox.text = "$results`n"                            })    $wpfexitbtn.add_click({  $form.close() | out-null  exit})  $form.showdialog() | out-null 

yes, psjobs "background" jobs.

when call start-job, separate process started, executing job/command.

in script, job doesn't block calling thread, subsequent command (wait-job $job) does.


if fire off start-job , return click handler, ui wouldn't lock up:

$button.add_click({   $jobcode = { start-sleep -seconds 10 }   $job = start-job $jobcode }) 

you'll see ui becomes responsive again in way lees 10 seconds.

the problem no longer have access $job , no longer control on when displayed.

to compensate this, need background thread or timed event can periodically check on job(s) , output result.

you use timer , powershell's builtin eventing infrastructure this:

# create timer $backgroundtimer = new-object system.timers.timer # set interval (ms) $backgroundtimer.interval = 500 # make sure timer stops raising events after each interval $backgroundtimer.autoreset = $false  # have powershell "listen" event in background register-objectevent $backgroundtimer -eventname 'elapsed' -sourceidentifier 'timerelapsed' -action {    # loop through completed jobs data return, "oldest" "newest"   while(($finishedjob = get-job |where-object {$_.state -eq 'completed' -and $_.hasmoredata}|select-object -first 1))   {     # update text box on wpf form results     # note: event executed in separate scope, "global:" scope prefix     $global:wpfstsbox.text = "$(receive-job $finishedjob)`n"      # clean job     remove-job $finishedjob   }    # restart timer   $backgroundtimer.start() }  # enable timer $backgroundtimer.enabled = $true 

Comments

Popular posts from this blog

how to insert data php javascript mysql with multiple array session 2 -

multithreading - Exception in Application constructor -

windows - CertCreateCertificateContext returns CRYPT_E_ASN1_BADTAG / 8009310b -