Domanda

Sto lavorando a un servizio Web per leggere i dati da un feed di terze parti, modificarli leggermente e archiviarli, quindi restituirli ai miei clienti.È sufficiente aggiornarlo periodicamente dal sito di terze parti.Verrà eseguito come servizio WCF in un ruolo Web in Azure.

All'inizio pensavo che avrei sempre fatto una chiamata al mio metodo parsefeed, ma avrei fatto in modo che la chiamata ritornasse se l'ultimo aggiornamento fosse stato troppo presto...

   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;            
        }
    }

Ma immagino che, poiché il recupero può richiedere 1-2 secondi (è un servizio Web), più utenti accederanno a quel codice contemporaneamente.

da http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607Poiché i membri statici di qualsiasi classe, inclusa una classe dell'applicazione, non sono thread-safe, il codice utente deve fornire un blocco appropriato per l'accesso ai membri statici.Questo si applica a qualsiasi membro statico aggiunto alla classe dell'applicazione.

  • Potrei usare il blocco (non so come) EDIT:molte informazioni Qui

  • Potrei evitare la var statica e utilizzare una cache e inserirvi i miei dati (ma verrebbe rimosso alla scadenza e più utenti proverebbero a recuperare i dati)

  • Potrei usare una cache con un falso elemento di dati al suo interno (sostanzialmente come un timer) e aggiornarla quando è scaduta, ma si aggiornerebbe anche se nessuno stesse colpendo il sito.(Potrebbe anche non essere thread-safe)

  • Non posso davvero utilizzare una cache di output perché i client interrogano i dati che restituisco in un modo che probabilmente rende unica ogni richiesta:il mio servizio ordina e filtra in base alla richiesta

A proposito, non sono preoccupato per la coerenza dei risultati su più istanze su Azure.Ognuno può recuperare il proprio, quindi non è necessario condividere lo stato su più server.

Ho la sensazione che esista una soluzione semplice, che mi è completamente sfuggita.Idee?

È stato utile?

Soluzione

Dalla tua domanda, sembra che:

  • Non è accettabile fornire dati scaduti da più di un minuto
  • È accettabile se due istanze del servizio restituiscono dati diversi a causa della mancata sincronizzazione dei tempi di aggiornamento
  • È accettabile che i chiamanti si blocchino per 1-2 secondi mentre i dati vengono aggiornati

Supponendo che siano tutte vere, la soluzione più semplice è semplicemente utilizzare una variabile statica per archiviare i dati, con a lock costruire attorno all'intero blocco di controllo/aggiornamento.Non mi preoccuperei nemmeno di provare a fare qualcosa di intelligente come il modello di blocco a doppio controllo;la contesa sui blocchi semplicemente non sarà un problema poiché il tempo trascorso nella regione critica impallidirà fino a diventare insignificante rispetto al sovraccarico di gestione di un servizio web, tranne quando si blocca e tutti devono comunque bloccarsi.

Altri suggerimenti

Dato che probabilmente leggerai dalla cache più di quanto scriverai, utilizzerei a ReaderWriterLockSlim per garantire che i dati possano essere letti da più thread contemporaneamente ma non scritti.Vorrei anche assicurarmi che i dati memorizzati nella cache siano immutabili per assicurarmi che non vengano alterati dai consumatori.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top