2

I have this following code block, which is receving a sessionId and need to return the related userId.

private static async Task<string> AddOrGetExisting(string sessionId, Func<Task<Tuple<string, DateTime>>> factory)
{
      var newValue = new Lazy<Task<Tuple<string, DateTime>>>(factory);
      var oldValue = _cache.AddOrGetExisting(sessionId, newValue, new CacheItemPolicy() { AbsoluteExpiration = (await newValue.Value).Item2 } ) as Lazy<Task<Tuple<string, DateTime>>>;
      try
      {
          return (await (oldValue ?? newValue).Value).Item1;
      }
      catch
      {
          _cache.Remove(sessionId);
          throw;
      }
}

Whenever I store a session, i want the cache to store it only until it expires.

The tuple contains the (string)UserId and (DateTime)ExpirationDate. The problem with what I wrote is that im invoking the factory all the time which fetches the data from the datebase which is kinda ruin the whole idea of cache.

How can I access the value only after/if it was retreived?

Ori Refael
  • 2,888
  • 3
  • 37
  • 68
  • Yes, the problem is that the expiration time is dependent on the calculated value. See https://stackoverflow.com/questions/31831860/async-threadsafe-get-from-memorycache and https://github.com/aspnet/Caching/issues/338. – Ohad Schneider Jul 08 '17 at 15:02
  • BTW the first line and the try/catch clause are redundant. And you should use a direct cast here, not `as`. – Ohad Schneider Jul 08 '17 at 15:02
  • An exceltion may be thrown, such as TaskCancelled or memory access issues or whats more important, my factory might throw one. Are you absolutly sure it is redundant? I have gotten any exception there, yet. – Ori Refael Jul 10 '17 at 04:46
  • In your second line (just before `try`) you already evaluate the expression `(await newValue.Value).Item2`. And like I said `oldValue` will never be null so the expression in your try block is equivalent to `(await oldValue.Value).Item2`. But when you put `oldValue` in the cache the first time it was `newValue`, meaning it was the same expression. If it didn't throw then, it won't throw now... – Ohad Schneider Jul 10 '17 at 22:45
  • although the question is old, this was really the question :) how can i make the expiration as the value. but i did it in a 3-phase thing. get oldvalue, if none get new value and insert with the expiration i have. – Ori Refael Jul 11 '17 at 12:29
  • You might want to answer (and probably accept) your own question. – Ohad Schneider Jul 11 '17 at 16:59

0 Answers0