2010-11-26 5 views
4

Je travaille sur un service Web pour lire les données d'un flux tiers, le modifier un peu et le stocker, puis le renvoyer à mes clients. Il suffit de mettre à jour à partir du site tiers régulièrement. Il sera exécuté en tant que service WCF dans un rôle Web dans Azure.Comment construire un cache de service Web en C#

Au début, je pensais que je voudrais juste toujours faire appel à ma méthode parsefeed, mais assurez-vous que le retour d'appel si la dernière mise à jour était trop tôt ...

public void ParseFeed() 
    { 
     if (DateTime.Now > lastrun.AddMinutes(1)) 
     { 
     //Fetch updated data into something shared here. 
     //thedata is a public static in Global class 
     thedata = fetchdata(); 
     lastrun=DateTime.Now;    
     } 
    } 

Mais je suppose que la récupération peut prendre 1-2s (c'est un service web) que plusieurs utilisateurs vont frapper ce code à la fois.

de http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607 Parce que les membres statiques de toute classe, y compris une classe d'application, ne sont pas thread-safe, le code utilisateur doit fournir le verrouillage approprié pour accéder aux membres statiques. Cela s'applique à tout membre statique que vous ajoutez à la classe d'application.

  • je pouvais utiliser le verrouillage (pas sûr) EDIT: beaucoup d'informations here

  • je pouvais éviter le var statique et utiliser un cache, et de mettre mes données (mais qui être supprimé à l'expiration et plusieurs utilisateurs essaieraient d'extraire les données)

  • Je pourrais utiliser un cache avec un faux élément de données dedans (fondamentalement comme une minuterie) et rafraichir quand ça expirait - mais ça rafraîchirait même si personne ne frappait le site. (Je ne peux pas non plus être thread-safe)

  • Je ne peux pas vraiment utiliser un cache de sortie parce que les clients interrogent les données que je retourne d'une manière qui rend chaque requête unique: mon service trie et filtre selon la demande

BTW Je ne suis pas préoccupé par la cohérence des résultats sur plusieurs instances sur Azure. Chacun peut aller chercher le sien, donc je n'ai pas besoin de partager l'état sur plusieurs serveurs.

J'ai l'impression qu'il existe une solution simple, que j'ai totalement manquée. Des idées?

+0

J'ai repéré ce http://stackoverflow.com/questions/39112/what-is-the-best-way-to-lock-cache-in-asp-net#40065 qui montre comment gérer les verrous. Cela pourrait s'appliquer à la plupart des options, et laisse toujours la question de savoir si utiliser le cache, les vars statiques ou s'il y a un mécanisme plus simple. – Andiih

Répondre

1

De votre question, il ressemble à:

  • Il est inacceptable de servir des données qui est plus d'une minute sur la date
  • Il est acceptable si deux instances de service renvoient des données différentes en raison de rafraîchir fois étant désynchronisée
  • Il est acceptable pour les appels à bloquer pendant 1-2 secondes alors que les données sont actualisées

sont en supposant que ces vrai, alors la solution la plus simple est juste pour utiliser une variable statique pour stocker les données, avec une construction lock autour de l'ensemble du bloc de vérification/actualisation.Je ne m'embêterais même pas à essayer de faire quelque chose d'intelligent comme le motif de verrouillage à double vérification; Le conflit de verrous ne sera tout simplement pas un problème car le temps passé dans la région critique deviendra insignifiant par rapport à la surcharge d'exploitation d'un service Web, sauf quand il bloque et que tout le monde doit bloquer de toute façon.

+0

Je dirais en fait qu'une fois que les données sont à jour data ie Il serait préférable d'initier un rafraîchissement non-bloquant en arrière-plan tout en servant des données périmées. D'un autre côté, si les données étaient dites une heure périmées (pas d'utilisation du jour au lendemain), alors je devrais bloquer aller chercher et revenir. – Andiih

+0

c'est la route avec laquelle je suis allé, bien que j'aie implémenté la vérification de verrouillage, car il y a peut-être un certain nombre d'utilisateurs bloqués pendant le chargement, qui essaieraient alors d'aller chercher autrement ... – Andiih

1

Étant donné que vous lirez probablement dans le cache plus que vous n'écrirez, j'utiliserais un ReaderWriterLockSlim pour que les données puissent être lues simultanément par plusieurs threads mais pas écrites. Je m'assurerais également que les données mises en cache sont immuables pour s'assurer qu'elles ne sont pas modifiées par les consommateurs.

Questions connexes