2014-12-01 2 views
3

Я хочу поместить токен аутентификации в кеш, где он может использоваться в нескольких доменах приложений. Этот токен истекает каждый час. Когда клиент не может авторизоваться с токеном, он просит службу генерации маркера генерировать новую.Асинхронный метод в блоке блокировки-оператора

Я только хочу, чтобы это восстановление произойдет в первый клиент, который не проверяет подлинность успешно, поэтому я использовал объект блокировки, как это:

public async Task<Token> GenerateToken(Token oldToken) 
{ 
    Token token; 
    lock (lockObject) 
    { 
     var cachedToken = GetTokenFromCache(); 
     if (cachedToken == oldToken) 
     { 
      var authClient = new AuthClient(id, key); 
      token = await authClient.AuthenticateClientAsync(); //KABOOM 
      PutTokenInCache(token); 
     } 
     else 
     { 
      token = cachedToken; 
     } 
    } 
    return token; 
} 

Мой вопрос AuthClient имеет только async методы и async методы запрещены в блоках блокировки. У меня нет никакого контроля над AuthClient, есть ли какая-то другая стратегия, которую я могу использовать здесь?

+0

Вы используете .NET 4.5 или .NET 4.5.1? –

+0

Я использую .NET 4.5 –

+0

Kinda [дубликат] (http://stackoverflow.com/q/21404144/1997232). – Sinatr

ответ

8

Вы можете использовать SemaphoreSlim в качестве основной асинхронной готовых lock замены:

private readonly SemaphoreSlim lockObject = new SemaphoreSlim(1); 
public async Task<Token> GenerateToken(Token oldToken) 
{ 
    Token token; 
    await lockObject.WaitAsync(); 
    try 
    { 
    var cachedToken = GetTokenFromCache(); 
    if (cachedToken == oldToken) 
    { 
     var authClient = new AuthClient(id, key); 
     token = await authClient.AuthenticateClientAsync(); 
     PutTokenInCache(token); 
    } 
    else 
    { 
     token = cachedToken; 
    } 
    } 
    finally 
    { 
    lockObject.Release(); 
    } 
    return token; 
} 
+0

Это выглядит великолепно! «Класс SemaphoreSlim представляет собой легкий, быстрый семафор, который можно использовать для ожидания в течение одного процесса, когда ожидаемое время ожидания будет очень коротким». Если для получения токена требуется до 5 секунд, есть ли проблемы с этим? –

+1

@MisterEpic: Нет. Однако если ваш кеш находится в памяти, вы можете рассмотреть кеширование * задачи * вместо * токена *, что немного упростит код. –

Смежные вопросы