How to manage cache in ASP.NET WebApi2?

后端 未结 3 938
忘了有多久
忘了有多久 2021-01-12 09:20

I have implemented REST service using WebAPI2, service implemeted to manage different sessions which are created and joined by different clients which are accessing service.

相关标签:
3条回答
  • 2021-01-12 09:50

    @ScottHanselman said about a bug in .NET 4 here. I hope this fix help you:

    The temporary fix:

    Create memory cache instance under disabled execution context flow

    using (ExecutionContext.SuppressFlow())     {
              // Create memory cache instance under disabled execution context flow
             return new YourCacheThing.GeneralMemoryCache(…);
    }
    

    The Hotfix is http://support.microsoft.com/kb/2828843 and you can request it here: https://support.microsoft.com/contactus/emailcontact.aspx?scid=sw;%5BLN%5D;1422

    0 讨论(0)
  • 2021-01-12 09:53

    You should store client specific information in Session instead of Cache. Cache should be for the whole application (shared)

    However, it's not recommended as web api is built with RESTful in mind and RESTful services should be stateless (APIs do not cache state). Stateless applications have many benefits:

    • Reduce Memory Usage
    • Better scalability: Your application scales better. Image what happens if you store information of millions of client at the same time.
    • Better in load balancing scenario: every server can handle every client without losing state.
    • Session expiration problem.

    In case you want to store client state, you could do it anyway. Please try the suggestions in the following post: ASP.NET Web API session or something?

    In general, caching state locally on the web server is bad (both Session and local MemoryCache). The cache could lose for many reasons:

    • App pool recycle.
    • Load balancing environment
    • Multiple worker processes in IIS

    Regarding your requirements:

    Each client get session information and access list from server for synchronization purpose on every second. According to access changed, client functionality will changed(Enable/Disable).

    I'm not sure if you want to update the other clients with new access list immediately when a client sends synchronization call. If that's the case, SignalR would be a better choice.

    Otherwise, you could just store the updated access list somewhere (shared cache or even in database) and update the other clients whenever they reconnect with another request.

    0 讨论(0)
  • 2021-01-12 09:55

    Just a caution, MemoryCache will keep data in memory in single server. So if you have multiple web servers(in front of load balancers), that cache will not be available to other servers. You also use the cache name - "SessionCollection". That data will be shared to all clients. If you need to store data in cache unique to each client, you need to return a token (guid) to the client and use that token to get/update data in cache in subsequent requests.

    Try introducing a class level variable. So your code will look like below. (Some code remove for clarity)

    private readonly MemoryCache _memCache = MemoryCache.Default;
    

    ....

    return _memCache.Get("SessionCollection") as List<Session>;
    

    ...

    _memCache .Add("SessionCollection", value, DateTimeOffset.UtcNow.AddHours(5));
    
    0 讨论(0)
提交回复
热议问题