从 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;
}
比方说我有这个代码:
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;
}