Home > database >  .Result operation doesn't block
.Result operation doesn't block

Time:12-31

I expect the following code to be blocked for almost 5 secs, but it is not. It immediately prints. Isn't Result operation blocking?

class Program
{
    static void Main()
    {
        // Return a value type with a lambda expression
        Task<int> task1 = Task<int>.Factory.StartNew(() => Task.Delay(5000).Id   100);
        int i = task1.Result;
        Console.WriteLine(i);
    }
}

CodePudding user response:

This code is not waiting for Delay to finish. It starts the delay and then return immediately Id 100. So, when the code reaches the Result operation, the task1 is almost always is in Completed state, so you get Result immediately.

You can try following to get desired behaviour

Task<int> task1 = Task.Run(async () => await Task.Delay(5000).Id   100);
int i = task1.Result;

Or better, use await instead of Result everywhere

Task<int> task1 = Task<int>.Factory.StartNew(async () => await Task.Delay(5000).Id   100);
int i = await task1;

or even

int i = await Task.Delay(5000).Id   100

(but I'm unsure here as you may have more logic inside the task in actual code)

CodePudding user response:

If you want to use the Task.Factory.StartNew() to perform an asynchronous operation use the TaskExtensions.Unwrap method:

Task<int> t = Task.Factory.StartNew(async delegate
    {
        var dt1 = DateTime.Now;

        var task = Task.Delay(5000);                
        await task;

        System.Diagnostics.Debug.WriteLine($"Delayed TotalMilliseconds {(DateTime.Now - dt1).TotalMilliseconds} ");                

        return task.Id   100;
    }).Unwrap();
    
var result = t.Result;

System.Diagnostics.Debug.WriteLine($"Result= {result}");

In my test this code printed:

Delayed TotalMilliseconds: 5007.7685 
Result= 103
  • Related