从 returns Task.FromResult(...) 的方法中读取 Task.Result 属性 是否安全?

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

比方说我有这个代码:

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

GetZero() 中,我直接从 GetZeroAsync() 返回的任务的 .Result 属性 中读取。直接从 .Result 属性 读取是否安全,因为返回的 Task 已经完成(即它会导致任何死锁、线程重复或上下文同步问题)吗?

我问的原因是因为在阅读 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 上的所有答案后,我急于使用 .Result

是的,获取已完成任务的 Result 是安全的。但是,如果你的程序的正确性依赖于正在完成的任务,那么你就有了一个脆弱的code-base。至少你应该在调试期间验证这个断言:

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

您可以考虑添加 run-time 检查。崩溃的程序可以说比死锁的程序要好。

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