为什么是任务?结果工作和任务等待不工作与GetItemAsync使用dynamodb

本文关键字:工作 任务 GetItemAsync 使用 dynamodb 结果 为什么 等待 | 更新日期: 2023-09-27 18:09:57

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(…)的方法调用时。

为什么是任务?结果工作和任务等待不工作与GetItemAsync使用dynamodb

两个函数都应该工作。如果有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有一个适当的重载来自动展开内部任务。