-2

I'm working in a simple timeout code for my http requests. I got this

private async Task<HttpResponseMessage> ExecuteIOTask(Task<HttpResponseMessage> ioTask, int timeout)
    {
        var timeoutTask = await Task.WhenAny(Task.Delay(timeout), ioTask);

        if (ioTask.IsCompleted)
            return ioTask.Result;

        throw new TimeoutException();
    }

After IsCompleted, is there any difference using Result vs await ? The task is already completed at that instance, so I think the performance should be the same. But i'm a little concern about the exception handling. I think Result is not going to propagate the exceptions but await will.

Is this correct?

  • 4
    You have a question about what a particular program does. **Such questions can be answered by running the program and seeing what happens**. You want to know if there is an exception handling difference between `await` and using `Result`, so *write the program both ways, cause an exception, and see if the program does two different things*, and then you will know! – Eric Lippert Mar 20 '19 at 19:33
  • Your code assigns to `timeoutTask` but then never uses the variable's value for anything; what is the purpose of that choice? – Eric Lippert Mar 20 '19 at 19:35
  • 1
    @FedericoCalvagna, instead of this design, maybe you should look at passing a `Task`-returning lambda to `ExecuteIOTask` rather than an already running task, and properly implement cancellation pattern for your IO operation, using `CancellationTokenSource` (which supports timing out). – noseratio Mar 20 '19 at 20:17

1 Answers1

0

Do not use .Result, always use await.

Please note that .Result can cause deadlocks and can cause some unpredictable behaviors in the applications.

The only way then would be to take the process dump and then analyze dump in procdump. Believe me it is going to be very difficult debugging.

Please find best practices about async programming at this blog.

As far as exception handling is concerned, it is mentioned in this blog that:

Every Task will store a list of exceptions. When you await a Task, the first exception is re-thrown, so you can catch the specific exception type (such as InvalidOperationException). However, when you synchronously block on a Task using Task.Wait or Task.Result, all of the exceptions are wrapped in an AggregateException and thrown.

Hope this helps.

Manoj Choudhari
  • 5,277
  • 2
  • 26
  • 37
  • 7
    How can `Result` cause a deadlock if `IsCompleted` is true? Can you give an example of such a scenario? – Eric Lippert Mar 20 '19 at 19:32
  • 3
    This answer does not answer the question that was asked, which was "**I think Result is not going to propagate the exceptions but await will. Is this correct?**" – Eric Lippert Mar 20 '19 at 19:34
  • @EricLippert - the answer is to follow the best practice and that statement does not consider the IF statement. Also, the exceptions part was mentioned in the async programming blog URL, i have copied it in the answer for better clarity. – Manoj Choudhari Mar 20 '19 at 19:44