2009-01-22 2 views
21

프로세스가 완료 될 때까지 기다리고 싶지만 process.WaitForExit()은 내 GUI를 정지시킵니다. 이벤트 기반 방식이 있습니까? 아니면 종료 할 때까지 차단할 스레드를 생성 한 다음 직접 이벤트를 위임해야합니까?process.WaitForExit() 비동기식

+0

다음은 표준 출력과 표준 오류 스트림 (http://stackoverflow.com/a/39872058/1212017)을 리디렉션 할 수있는 ** 완전 비동기 ** 구현입니다. –

답변

1

사용 System.Diagnostics.Process.Exited

4

According to this link WaitForExit() 메소드는 관련 프로세스가 종료 될 때까지 현재 스레드의 대기를 위해 사용된다. 그러나 프로세스에는 연결할 수있는 Exited 이벤트가 있습니다.

+3

다음은이 무엇입니까? http://msdn.microsoft.com/en-us/library/system.diagnostics.process.exited.aspx –

+0

사실이 아니고, 대답은 내 생각에 콜레트 하향 선이 아니라 삭제되어야합니다. –

55

.NET 4.0/C# 5부터 비동기 패턴을 사용하여 이것을 표현하는 것이 더 좋습니다.

/// <summary> 
/// Waits asynchronously for the process to exit. 
/// </summary> 
/// <param name="process">The process to wait for cancellation.</param> 
/// <param name="cancellationToken">A cancellation token. If invoked, the task will return 
/// immediately as canceled.</param> 
/// <returns>A Task representing waiting for the process to end.</returns> 
public static Task WaitForExitAsync(this Process process, 
    CancellationToken cancellationToken = default(CancellationToken)) 
{ 
    var tcs = new TaskCompletionSource<object>(); 
    process.EnableRaisingEvents = true; 
    process.Exited += (sender, args) => tcs.TrySetResult(null); 
    if(cancellationToken != default(CancellationToken)) 
     cancellationToken.Register(tcs.SetCanceled); 

    return tcs.Task; 
} 

사용법 : 당신이 @MgSam의 답을 선택하면 자동으로 지정된 지연 후 취소 할 것, WaitForExitAsync 일부 CancellationToken를 통과 할 경우

public async void Test() 
{ 
    var process = new Process("processName"); 
    process.Start(); 
    await process.WaitForExitAsync(); 

    //Do some fun stuff here... 
} 
+1

감사합니다. 도움이되었습니다. 한 가지 확실한 점은 태스크가 이미 취소 된 경우'tcs.SetResult (null)'이'InvalidOperationException'을 throw한다는 것입니다. 이는 태스크가 취소 된 후에 프로세스가 종료 될 때 발생할 수 있습니다. 이 문제를 해결하기 위해'tcs.SetResult'를'tcs.TrySetResult'로 대체했습니다. –

+0

@aj_r 좋은 팁. 감사. 나는 갱신을했다. – MgSam

+4

Exited 핸들러를 등록하기 전에 프로세스가 중지되면 우리는 영원히 기다리고 있습니다. 시작 전에 등록을 완료해야 StartAsync 메서드를 작성하는 것이 훨씬 쉽습니다. 대체로 같은 코드이지만 Process로 StartAsync를 명명했습니다. 반환 선 앞에 시작()이 붙습니다. – MuiBienCarlota

6

이, 알고, 당신이 InvalidOperationException를 얻을 수 있습니다. 이 문제를 해결하려면, 당신은

cancellationToken.Register(tcs.SetCanceled); 

cancellationToken.Register(() => { tcs.TrySetCanceled(); }); 

에 P.S을 변경해야합니다 : 시간에 CancellationTokenSource을 처분하는 것을 잊지 마세요.

+0

그 P. 내 생명을 구했어 .... – Fazi