2015-10-16 63 views
0

我開始Process並想以異步的方式撥打WaitForExit。使用另一個堆棧溢出的答案爲模板,我有這樣的擴展方法來做到這一點:如何避免擴展方法中的TaskCanceledException?

public static class ProcessExtensions 
{ 
    public static Task WaitForExitAsync(this Process process, int milliseconds) 
    { 
     var tcs = new TaskCompletionSource<object>(); 
     process.EnableRaisingEvents = true; 
     process.Exited += (sender, args) => tcs.TrySetResult(null); 

     var cts = new CancellationTokenSource(milliseconds); 
     cts.Token.Register(() => tcs.TrySetCanceled()); 

     return tcs.Task; 
    } 
} 

這樣,我可以打電話await process.WaitForExitAsync(1000)來完成我想要的東西。如果任務在超時發生之前退出,那麼一切都很好。但是我遇到的問題是,當超時時間被擊中時,它只會拋出一個TaskCanceledException。擴展方法的要點是在一行中優雅地處理事務。當我只是想讓它繼續任何一種方式時,我都不需要將這個調用包裝起來。我該如何做到這一點?

請原諒我的壞問題標題,順便說一句。我無法想象如何簡潔地表達這一點。

+1

請注意,您可能希望在完成此任務後刪除「退出」事件處理程序,而不是將其留在那裏。特別是在任務被取消的情況下,但即使在其他情況下也是如此。 – Servy

回答

2

如果您希望返回的任務成功完成而不是取消,那麼取消令牌時,只需在取消令牌時調用TrySetResult而不是TrySetCancelled。當您致電TrySetCancelled時,您明確告訴TCS將該任務標記爲已取消。

相關問題