ConcurrentDictionary
을 사용하여 느린 소스 (예 : 데이터베이스)에서 가져온 캐시 된 데이터를 보관하려고합니다..NET ConcurrentDictionary GetOrAdd 메서드가 비동기 메서드를 호출 할 수 있습니까?
데이터베이스 호출은 async
입니다. 따라서 항목이 사전에없는 경우 동시 사전 호출을 비동기 호출로 호출 할 수 있습니까? 예를 들어
:
const int userId = 1;
var cachedUsers = new ConcurrentDictionary<int, Task<User>>();
var user = await cachedUsers.GetOrAdd(userId, val => GetSlowDbResultAsync(userId, cancellationToken));
그래서 위의 일을하려고된다 pseduo 코드가 말하는 무엇 : 사용자 # 1은 C-DICT에
- 존재 하는가?
- 예, 확인해주세요.
- 아니요, Db의 사용자 # 1을 붙잡아 캐시에 고정하십시오.
그래서 - (키/값의 경우) 동시 사전의 '값'으로 Task<User>
를 넣어 :
- 것이 괜찮습니다?
- 는 제가 위에서 쓴 코드이 허용 가능한 사용합니까 또는 그냥 비동기/await를/C#
노트 신성한 모든 것을 학대 한 :
이 질문은 inspired from my question on twitter입니다.
이것은 previous question I asked과 유사하지만 큰 견인력을 얻지 못했습니다. 확장 메서드에 대한
class Extension
{
public static User Get(this ConcurrentDictionary<int, User> conDict, int userID)
{
User user = null;
if (!conDict.TryGetValue(userID, out user))
{
user = GetSlowDbResultAsync(userId, cancellationToken)
conDict.TryAdd(userID, user);
}
return user;
}
}
자세한 내용은이 article 확인하시기 바랍니다 : 확장 메서드를 작성하는 시도 같은 것에 대해 어떻게
GetAsync 메서드로이를 마무리하면 (클라이언트가 구현을 이해할 필요가 없도록), 괜찮을 것이라고 생각합니다. 첫 번째 조회에서는 데이터베이스 호출을 기다리고 두 번째 조회 (동일한 사용자 ID의 경우)에서 완료된 태스크를 기다리게됩니다. 나에게 좋을 것 같다. – john
왜 'ConcurrentDictionary'를 선택 했습니까? 당신이 비동기를 사용하지 않기를 바래요. – CodingYoshi
중복 표시된 부분을 참조하십시오. 그 대답은 당신이 요구하는 기술을 정확하게 사용합니다. 코드의 나머지 부분이 그것을 수용하도록 작성되었다고 가정하면 잘 동작합니다. –