これはかなり正直な質問です。私は、たくさんのファイルを読み込むdllを持っています。すべてのファイルの完了はイベントによって示されます。コンソールアプリケーションは、argsからの情報を表示するとすぐにそれを処理します。Powershellの.NETイベントは終了まで処理されません
私はこのdllをpowershellスクリプトから実行し、プログレスバーを表示したいと思います。期待どおりに動作しません。 実行の最後にプログレスバーが表示され、0〜100%の間に素早く上昇して消滅します。
$isVerbose = $PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent
$finder = New-Object ContentFinder.LogFinder
if($isVerbose)
{
Register-ObjectEvent -InputObject $finder -EventName "FileQueueProgress" -Action {Write-Progress ($EventArgs.Percent)} -SourceIdentifier "FileReadingProgressIndicator" | Out-Null
}
try
{
$path = GetPath
$date = GetDate
return $finder.GetErrorLogs($path, $date)
}
catch
{
Write-Host ($_.Exception.Message)
}
finally
{
if($isVerbose)
{
Unregister-Event -SourceIdentifier "FileReadingProgressIndicator"
}
Write-Host "Done"
}
、それはこのように呼ばれています:Get-ErrorLogs -Verbose
。通常、私は結果をフィルターに掛けることができるように変数に代入します。 PSが彼らと同じ瞬間にイベントに応答するためにできることはありますか?
EDIT:コメントからANSWER これは予想と同じように動作します。スクリプトの最後ではなく、実行中に進捗を報告します。
if($isVerbose)
{
$Handler = {Write-Progress ($args[1].Percent)} -as $finder. PSObject. Members. Match('FileQueueProgress')[0]. Value. EventHandlerType;
$finder. add_FileQueueProgress($Handler);
#Register-ObjectEvent -InputObject $finder -EventName "FileQueueProgress" -Action {Write-Progress ($EventArgs.Percent)} -SourceIdentifier "FileReadingProgressIndicator" | Out-Null
}
try
{
$path = GetPath
$date = GetDate
return $finder.GetErrorLogs($path, $date)
}
catch{
Write-Host ($_.Exception.Message)
}
finally
{
if($isVerbose)
{
#Unregister-Event -SourceIdentifier "FileReadingProgressIndicator"
$finder. remove_FileQueueProgress($Handler)
}
Write-Host "Done"
}
'GetErrorLogs'はどのように機能しますか?それは操作の終わりまでブロックしていますか? 'GetErrorLogs'が呼び出された同じスレッドで' FileQueueProgress'が呼び出されましたか? – PetSerAl
はい、同期して実行され、その間に同じスレッドでイベントが発生します。 – yoger
コンソールのバージョンはPowerShellのバージョンとどのように比較されますか?私はあなたが見ている行動が期待されると思います。 PowerShellでは非同期なものは何もないので、すべてがキューに入れられます。少なくともそれは私がそれを理解する方法です。 –