2016-04-11 52 views
2

我正在使用:https://stackoverflow.com/a/19104345/2713516中提供的解決方案來運行WaitForExit異步,但是,我想使用Int32參數過載(https://msdn.microsoft.com/en-us/library/ty0d8k56(v=vs.110).aspx),如在process.WaitForExit(10000)中一樣。異步process.WaitForExit(int32)

如何修改此擴展方法,使其與超時參數一起使用?

方問題:我還看到有人提到(https://stackoverflow.com/a/32994778/2713516),我應該處置的CancellationToken在某些時候,不應該使用一個dispose /使用,則該方法內?如何?

/// <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; 
} 
+0

你可以從http://stackoverflow.com/questions/25683980/timeout使用「沒有內置超時」模式-pat-on-task-based-asynchronous-method-in-c-sharp –

+0

你已經傳遞了一個'CancellationToken' - 這比超時更有用。在超時過後,例如剛剛取消'新的CancellationTokenSource(超時).Token'。 – Luaan

+0

感謝您的建議 – user2713516

回答

2

您需要更改方法簽名並應用過程本身的結果。例如考慮以下內容:

/// <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, 
    int milliseconds, 
    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 Task.WhenAny(tcs.Task, Task.Delay(milliseconds)); 
} 

現在,如果進程還沒有結束,任務仍然會在延遲後返回。另一種方法是與調用做Task.Run像這樣希望的過載:

/// <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, 
    int milliseconds, 
    CancellationToken cancellationToken = default(CancellationToken)) 
{  
    return Task.Run(() => process.WaitForExit(milliseconds), cancellationToken); 
} 
+0

我會與第一個去,謝謝 – user2713516