为什么 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
有一个适当的重载来自动解包内部任务。
这行得通:
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
有一个适当的重载来自动解包内部任务。