2010年11月21日日曜日

◆バックグラウンドジョブの終了イベントを受け取る

Powershell2.0ではジョブをバックグラウンドで実行する機能が追加になっていて比較的簡単に使える。

20101121101144 
これらの名前を見ただけでなんとなく想像はつく。
ちなみに、ここら辺の整然としたコマンド体系がPowershellのすばらしいところですね。いまだにDOSのバッチファイルなどでゴニョゴニョしている人はぜひPowershellに移行しましょう

バックグラウンドジョブの基本は以下のサイトで詳しく解説がなされているので参考にすると良いだろう。
PowerShell 2.0の新機能(3) ――バックグラウンドジョブ編(1/5):CodeZine

Start-Jobでジョブを開始し、Get-Jobで状態を確認することができる。終了したらReceive-Jobで結果を取得。となるのだが、Get-Jobを連打して終了を待つのも芸がない。コールバックしてほしいところだ。

というわけでジョブの結果オブジェクトを見てみると、おぉーちゃんとあるじゃないですか
20101121160902

StateChangedイベント。これにイベントハンドラーを登録すれば良さそうだ。
Powershell2.0からRegister-ObjetEventコマンドレットが追加になっており、これで登録が可能だ。Actionパラメータにスクリプトブロックを指定してあげれば良い。

以下のような感じだ。

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
$job = Start-Job { 
Dir $env:windir *.jpg -r  -ea SilentlyContinue} -Name "WinDirの検索"

Register-ObjectEvent $job -EventName StateChanged  `
  -SourceIdentifier JobStateChanged `
  -Action { 
  Write-Host "JOb「$($sender.Name)」が $($event.TimeGenerated) に終了" 
  Write-Host "★結果は★"
  Receive-Job -Id ($sender.id) | Write-Host

  $global:sender1 = $sender
  $global:event1 = $Event
  $global:subscriber = $EventSubscriber
  $global:source = $SourceEventArgs
  $global:SourceArgs1 = $SourceArgs

  Unregister-Event -SourceIdentifier JobStateChanged
}

ヘルプによるとActionパラメータの中では$sender,$evnet,$eventSbuscriber,$sourceEventArgs,$sourceArgsの自動変数が参照可能だとあるが、確認した限りでは最後の2つは何も入ってこなかった。
ちなみに上記ソースでglobal変数に退避しているのは、処理には全く関係なく後から情報を調べたかったためだ。バックグラウンドジョブなのでglobalスコープにしておかないと後から参照できない。

また、ここでは発生するイベントをCompletedだと決め打ちして処理しているが実際にはイベントの種類を判定して処理を振り分ける必要がある。イベントには以下のようなものがある。

JobState Enumeration (System.Management.Automation)

Blocked The job is blocked, such as waiting for user input, from running the commands of the pipeline in one or more runspaces. This field is introduced in Windows PowerShell 2.0.
Completed The job has successfully run the commands of the pipeline in all runspaces. This field is introduced in Windows PowerShell 2.0.
Failed The job was not able to successfully run the commands of the pipeline. This field is introduced in Windows PowerShell 2.0.
NotStarted The job has not begun to run the commands of the pipeline. This field is introduced in Windows PowerShell 2.0.
Running The job is in the process of running the commands of the pipeline. This field is introduced in Windows PowerShell 2.0.
Stopped The job has been cancelled on one or more runspace. This field is introduced in Windows PowerShell 2.0.

ちょっとここで考えるのがCompletedとそれ以外だけで判定して良いのかという事である。
たとえば、Blockedで始まりそのあとにRunningになるなんてことがないのかどうか。
ここら辺は資料を見つけられなかったので実際に試しながらとなるのかもしれない。
システムに負荷を掛けて何度か試した限りにおいては大丈夫そうではあった。

ちなみにこのスクリプトの結果は以下の通り。
20101121164341

これを見るとイベントハンドラーに登録した処理もバックグラウンドジョブとして登録されているのが判る。

0 件のコメント:

コメントを投稿