Asynchronously wait for Task to complete with timeout

后端 未结 16 2261
天命终不由人
天命终不由人 2020-11-21 17:49

I want to wait for a Task to complete with some special rules: If it hasn\'t completed after X milliseconds, I want to display a message to the user. And

16条回答
  •  孤城傲影
    2020-11-21 18:45

    I'm recombinging the ideas of some other answers here and this answer on another thread into a Try-style extension method. This has a benefit if you want an extension method, yet avoiding an exception upon timeout.

    public static async Task TryWithTimeoutAfter(this Task task,
        TimeSpan timeout, Action successor)
    {
    
        using var timeoutCancellationTokenSource = new CancellationTokenSource();
        var completedTask = await Task.WhenAny(task, Task.Delay(timeout, timeoutCancellationTokenSource.Token))
                                      .ConfigureAwait(continueOnCapturedContext: false);
    
        if (completedTask == task)
        {
            timeoutCancellationTokenSource.Cancel();
    
            // propagate exception rather than AggregateException, if calling task.Result.
            var result = await task.ConfigureAwait(continueOnCapturedContext: false);
            successor(result);
            return true;
        }
        else return false;        
    }     
    
    async Task Example(Task task)
    {
        string result = null;
        if (await task.TryWithTimeoutAfter(TimeSpan.FromSeconds(1), r => result = r))
        {
            Console.WriteLine(result);
        }
    }    
    

提交回复
热议问题