Home > Software engineering >  Is it safe to read the Task.Result property from a method that returns Task.FromResult(...)?
Is it safe to read the Task.Result property from a method that returns Task.FromResult(...)?

Time:05-21

Let's say for example I have this code:

public static class MyClass
{
    private static async Task<int> GetZeroAsync()
    {
        return await Task.FromResult(0);
    }
    public static int GetZero()
    {
        return GetZeroAsync().Result;
    }
}

In GetZero(), I am directly reading from the .Result property of the Task that's returned from GetZeroAsync(). Is it safe to read directly from the .Result property, since the returned Task is already completed (i.e. will it incur any deadlocks, thread duplication, or context synchronization issues)?

The reason I'm asking is because after reading all of the answers at How to call asynchronous method from synchronous method in C#? as well as Stephen Cleary's article here https://msdn.microsoft.com/en-us/magazine/mt238404.aspx, it makes me anxious to use .Result.

CodePudding user response:

Yes, it is safe to get the Result of a completed task. But if the correctness of your program relies on the task being completed, then you have a fragile code-base. At least you should verify this assertion during debugging:

public static int GetZero()
{
    var task = GetZeroAsync();
    Debug.Assert(task.IsCompleted);
    return task.Result;
}

You might consider adding instead a run-time check. A program that crashes is arguably better than a program that deadlocks.

public static int GetZero()
{
    var task = GetZeroAsync();
    if (!task.IsCompleted)
        throw new InvalidOperationException("The task is not completed.");
    return task.Result;
}
  • Related