简体   繁体   中英

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

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

When calling the method with something like var result = GetClientDataAsync(...).Result The second one hangs forever.

Both functions should work. If the one with await is hanging forever it indicates that there is a SynchronizationContext present that tries to synchronise all tasks to a single thread and that thread is hanging due to something that is happening outside of this function.

That is a very common case if the function is called from the context of WPF or Windows Forms and the result of the function is fetched by .Result or the completion is awaited by using the .Wait function.

Check System.Threading.SynchronizationContext.Current for the presence of a synchronization context.

You should try to avoid mixing synchronous waiting ( .Wait , .Result ) and asynchronous waiting ( await ). Mixing both causes deadlocked situations especially when dealing with a SynchronizationContext very easily.

So I suggest you get rid of the .Result and call your function like this:

await GetClientDataAsync(...)

Or you get rid of the SynchronizationContext by forcing the function into the thread pool (that does not have a SynchronizationContext like so:

Task.Run(() => GetClientDataAsync(...)).Result

Task.Run has a proper overload to do that that automatically unwraps the inner task.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM