THIS WORKS:
public static async Task<T> GetClientDataAsync(string id)
{
var task = dynamoDBClient.GetItemAsync(new GetItemRequest
{
TableName = "x",
Key = new Dictionary<string, AttributeValue>
{
{ "ID", new AttributeValue { S = id } }
}
}).Result;
return task.IsItemSet ? task.Item : null;
}
THIS DOES NOT:
public static async Task<T> GetClientDataAsync(string id)
{
var task = await dynamoDBClient.GetItemAsync(new GetItemRequest
{
TableName = "x",
Key = new Dictionary<string, AttributeValue>
{
{ "ID", new AttributeValue { S = id } }
}
});
return task.IsItemSet ? task.Item : null;
}
使用类似var result = GetClientDataAsync(…)的方法调用时。
两个函数都应该工作。如果有await
的一个永远挂起,它表明有一个SynchronizationContext
存在,试图将所有任务同步到一个线程,并且该线程由于在此函数之外发生的事情而挂起。
这是一个非常常见的情况,如果从WPF或Windows窗体的上下文中调用函数,函数的结果由.Result
获取或使用.Wait
函数等待完成。
检查System.Threading.SynchronizationContext.Current
是否存在同步上下文。
你应该尽量避免混合同步等待(.Wait
, .Result
)和异步等待(await
)。混合使用这两种方法会导致僵局,尤其是在处理SynchronizationContext
非常容易的情况下。
所以我建议你摆脱.Result
并像这样调用你的函数:
await GetClientDataAsync(...)
或者您可以通过强制函数进入线程池(没有SynchronizationContext
的线程池)来摆脱SynchronizationContext
:
Task.Run(() => GetClientDataAsync(...)).Result
Task.Run
有一个适当的重载来自动展开内部任务。