View Single Post
Old 10-30-2006   #1 (permalink)
OK


 
 

Run tasks asynchronously: external files vs. script blocks

I need to run few chained tasks asynchronously AND pass parameters down to
the chain.
(At the very bottom is “short” description, what I’m trying to do)

I can run tasks asynchronously using external files, but can not do the same
with script blocks...

Below is an example:
There are two files there f1.ps1 and f2.ps1

This example works with external files.
To change it to work with scriptblocks all you have to do is uncomment all
lines started with #2 AND comment corresponding previous lines (#1).


[[[[[[[[[[[[[[[[[cut here]]]]]]]]]]]]]]]]]

# f1.ps1

[scriptblock] $f2_script = {
param( [string] $p1 )

"hello world parameter1: $p1 input: $input"
}

[string] $f2_file = "./f2.ps1"

#------------------------------------------------------------------------------
#1
function invokeAsync([string] $command, [DateTime] $a) {
#2 function invokeAsync([scriptblock] $script, [DateTime] $a) {

[System.Management.Automation.Runspaces.RunspaceConfiguration] $config =
[System.Management.Automation.Runspaces.RunspaceConfiguration]::Create();
[System.Management.Automation.Runspaces.Runspace] $runspace =
[System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace($host, $config);
$runspace.Open()


#1
[System.Management.Automation.Runspaces.Command] $cmd = new-object
System.Management.Automation.Runspaces.Command($command, $false, $false);
#2 [System.Management.Automation.Runspaces.Command] $cmd = new-object
System.Management.Automation.Runspaces.Command($script, $true, $false);

[System.Management.Automation.Runspaces.CommandParameterCollection] $cpc =
$cmd.Parameters;
$cmd.Parameters.Add("p1", $a);

[System.Management.Automation.Runspaces.Pipeline] $pipeline =
$runspace.CreatePipeline();
$pipeline.Commands.Add($cmd);


foreach($private:x in $input) {
$pipeline.Input.Write($x) > $null
}
$pipeline.Input.Close();

if($true) {
# if($false) {
foreach($private:x in $pipeline.Commands) {
Write-Host ("CommandText {0}" -f $x.CommandText)
Write-Host ("IsScript {0}" -f $x.IsScript)
Write-Host ("UseLocalScope {0}" -f $x.UseLocalScope)
}
}

$pipeline.InvokeAsync();


while($pipeline.PipelineStateInfo.State -eq
[System.Management.Automation.Runspaces.PipelineState]::Running) {
Start-Sleep -milli 100
}


foreach($private:result in $pipeline.Output.ReadToEnd()) {
Write-Host ("1-- Value {0}" -f $result)
}

foreach($private:result in $pipeline.Error.ReadToEnd()) {
Write-Host ("2-- Value {0}" -f $result)
}
}


#------------------------------------------------------------------------------
#-- Main script
---------------------------------------------------------------
#------------------------------------------------------------------------------

[DateTime] $private:a = [DateTime]::Now;

#1
($a, $a) | invokeAsync $f2_file $a
#2 ($a, $a) | invokeAsync $f2_script $a

#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------

[[[[[[[[[[[[[[[[[cut here]]]]]]]]]]]]]]]]]

# f2.ps1

param( [string] $p1 )
"hello world parameter1: $p1 input: $input"

#"hello world parameter1: $args input: $input"

[[[[[[[[[[[[[[[[[cut here]]]]]]]]]]]]]]]]]




-------------------------------------------------------------------------
-------------------------------------------------------------------------
-------------------------------------------------------------------------

Below is “short” description, what I’m trying to do:

Start backup databases on several servers simultaneously.
Like this
Server A backup db A1 A2 A3
Server B backup db B1 B2
Etc.

Due to some limitations I backup only one db from each server simultaneously.
I.e. A –A1 & B – B1 will run at the same time.

Once first backup is completed immediately
1. start archiving it ASYNCHRONOUSLY
2. start statistic recalculating for this db ASYNCHRONOUSLY
3. continue backing up next database.

Once all tasks is done, generate a report with all timing, when each task is
started and completed plus all totals including running totals.

I.e.
A – A1
backup started … completed … duration …
archiving started … completed … duration …
statistics …
A – A1 database total

A server total

Backup total…


Running tasks asynchronously is the easy part. Gathering totals in one place
is more difficult. Actually, it’s done already. But some questions are still
there...


My System SpecsSystem Spec