为什么 Task.Result 正在工作而 Task await 不能使用 dynamodb 与 GetItemAsync 一起工作?

Why is Task.Result working and Task await not working with GetItemAsync using dynamodb?

这行得通:

    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;
    }

这不是:

    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 有一个适当的重载来自动解包内部任务。