2009-01-22 58 views
21

我想等待一個進程完成,但process.WaitForExit()掛起我的GUI。有沒有基於事件的方式,還是我需要產生一個線程阻塞直到退出,然後自己委託事件?process.WaitForExit()異步

+0

這是一個完全異步**實現的``進程`,可以讓你重定向標準輸出和標準錯誤流http://stackoverflow.com/a/39872058/1212017。 – 2016-10-05 11:05:46

回答

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 – 2011-06-19 21:35:36

+0

不是真的,答案應該刪除,而不是collent downvotes我猜。 – 2017-08-03 15:36:51

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; 
} 

用法:

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

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

謝謝,這很有幫助。但是,我曾經遇到的一件事是,如果任務已被取消,`tcs.SetResult(null)`將拋出一個`InvalidOperationException`,如果任務被取消後該進程退出可能會發生這種情況。爲了解決這個問題,我用`tcs.TrySetResult`替換了`tcs.SetResult`。 – 2014-10-13 15:22:41

6

如果選擇@MgSam答案,要知道,如果你通過WaitForExitAsync一些CancellationToken,將在指定延遲後自動取消,你可以得到一個InvalidOperationException。爲了解決這個問題,你需要改變

cancellationToken.Register(tcs.SetCanceled); 

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

P.S:不要忘記處置您CancellationTokenSource的時間。