2017-02-03 1 views
1

매우 직접적인 질문입니다. 나는 수많은 파일을 읽는 책임이있는 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와 동일한 순간에 이벤트에 응답하도록하기 위해 할 수있는 일이 있습니까?

편집 : 대답 의견에서 이것은 예상대로 작동합니다. 스크립트가 끝날 때 실행되는 동안 진행 상황을보고하지 않습니다.

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" 
} 
+0

'GetErrorLogs'는 어떻게 작동합니까? 수술이 끝날 때까지 막히고 있습니까? 'GetErrorLogs'가 호출 된 동일한 스레드에서'FileQueueProgress'가 발생합니까? – PetSerAl

+0

예. 동 기적으로 실행되며 이벤트는 같은 스레드에서 발생합니다. – yoger

+0

콘솔 버전은 PowerShell 버전과 어떻게 비교됩니까? 나는 당신이 보는 행동이 기대된다고 생각합니다. PowerShell에는 비동기가 없으므로 모든 것이 대기열에 들어갑니다. 적어도 그것은 그것을 이해하는 방법입니다. –

답변

1

실제로 단일 스레드 시나리오에서는 Register-ObjectEvent을 사용할 필요가 없습니다. PowerShell을 사용하면 스크립트 블록을 대리자 형식 개체로 변환 할 수 있습니다. 이벤트 접근 자 (add_EventName/remove_EventName)를 직접 호출하여 해당 대리자를 이벤트에 연결하거나 분리 할 수 ​​있습니다.

$finder = New-Object ContentFinder.LogFinder 

if($isVerbose) 
{ 
    $Handler = {Write-Progress ($args[1].Percent)} -as $finder.PSObject.Members.Match('FileQueueProgress')[0].Value.EventHandlerType 
    $finder.add_FileQueueProgress($Handler) 
} 

try 
{ 
    $path = GetPath 
    $date = GetDate 

    return $finder.GetErrorLogs($path, $date) 
} 
catch 
{ 
    Write-Host ($_.Exception.Message) 
} 
finally 
{ 
    if($isVerbose) 
    { 
     $finder.remove_FileQueueProgress($Handler) 
    } 

    Write-Host "Done" 
} 

참고 : 나는 $Handler 변수에 위임 개체를 저장, 그래서 제대로 나중에 분리 할 수 ​​있습니다.

관련 문제