2009-04-09 10 views
5

Prima di tutto, vorrei che lo storage basato sul contesto fosse coerente in tutto il framework!Ricerca di spazio di archiviazione basato su dimensioni di un solo ingombro

Con ciò detto, sto cercando una soluzione elegante per rendere queste proprietà sicure su ASP.NET, WCF e qualsiasi altro codice .NET multithread. Le proprietà si trovano in alcuni helper di tracciamento di basso livello (questi sono esposti tramite metodi se ti stai chiedendo perché sono interni).

Preferisco non avere una dipendenza da assembly non necessari (come System.Web, ecc.). Non voglio richiedere a nessuno che usi questo codice di configurare qualcosa. Voglio solo che funzioni;) Questo potrebbe essere troppo alto per un ordine ...

Qualcuno ha qualche asso nella manica? (Ho visto l'implementazione di primavera)

internal static string CurrentInstance 
    { 
     get 
     { 
      return CallContext.LogicalGetData(currentInstanceSlotName) as string; 
     } 
     set 
     { 
      CallContext.LogicalSetData(currentInstanceSlotName, value); 
     } 
    } 

    internal static Stack<ActivityState> AmbientActivityId 
    { 
     get 
     { 
      Stack<ActivityState> stack = CallContext.LogicalGetData(ambientActivityStateSlotName) as Stack<ActivityState>; 
      if (stack == null) 
      { 
       stack = new Stack<ActivityState>(); 
       CallContext.LogicalSetData(ambientActivityStateSlotName, stack); 
      } 

      return stack; 
     } 
    } 

Aggiornamento

Di sicuro non intendo sincronizzati. Contesto del problema here

+0

Non ho molto da offrire, ma sono anche interessato a questo problema. FWIW Ricordo di aver visto in qualche repository sorgente (probabilmente Castle, NInject o NHibernate) diverse implementazioni di qualcosa come IContext che immagino siano destinate ad essere inserite in un'app. Ogni implementazione di IContext utilizzava una tecnologia diversa (CallContext, HttpContext, Thread.SetData, ecc.). Non so esattamente come dovevano essere usati, ma il mio primo pensiero è stato quello di astrarre "Contesto". Ad ogni modo, posso vedere se riesco a trovare quello che ho trovato prima e pubblicare un link. Potrebbe essere utile. – wageoghe

risposta

0

Non so che l'utilizzo di CallContext è la mossa giusta qui se il desiderio è semplicemente quello di fornire accesso sicuro ai thread alle proprietà. Se questo è il caso, l'affermazione di blocco è tutto ciò di cui hai bisogno.

Tuttavia, è necessario assicurarsi che si sta applicando correttamente.

Con CallContext, si otterrà accesso sicuro ai thread perché si avranno istanze separate di CallContext quando le chiamate arrivano su thread diversi (o negozi diversi, piuttosto). Tuttavia, è molto diverso dal rendere l'accesso a una risorsa thread-safe.

Se si desidera condividere lo stesso valore su più thread, l'istruzione di blocco è la strada da percorrere. Altrimenti, se si desidera valori specifici su una base per thread/chiamata, utilizzare CallContext o utilizzare i metodi statici GetData/SetData nella classe Thread o l'attributo ThreadStatic (o qualsiasi numero di meccanismi di archiviazione basati su thread).

+0

Non mi interessa la sincronizzazione. Come hai detto tu, ci sono molti meccanismi per l'archiviazione basata sul contesto e alcuni non funzionano in determinate situazioni (ad esempio CallContext e ThreadStatic in ASP.NET), quindi la mia domanda. – jsw

2

Ecco un link per (almeno in parte) di NHibernate implementazione "contesto":

https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/src/NHibernate/Context/

Non mi è chiaro esattamente dove e come questo entra in gioco nel contesto di NHibernate. Cioè, se volessi memorizzare alcuni valori nel "contesto" otterrei "il contesto" da NHibernate e aggiungerei i miei valori? Non uso NHibernate, quindi non lo so davvero.

Suppongo che si potrebbe cercare e determinare da soli se questo tipo di implementazione sarebbe utile a voi. Apparentemente l'idea sarebbe quella di iniettare l'implementazione desiderata, a seconda del tipo di applicazione (ASP.NET, WCF, ecc.). Questo probabilmente implica qualche configurazione (forse minima se si dovesse usare MEF per caricare "l'interfaccia" ICurrentSessionContext).

Ad ogni modo, ho trovato questa idea interessante quando l'ho trovato qualche tempo fa durante la ricerca di informazioni su CallContext.SetData/GetData/LogicalSetData/LogicalGetData, Thread.SetData/GetData, [ThreadStatic], ecc

Inoltre, in base all'utilizzo del CallContext.LogicalSetData piuttosto che CallContext.SetData, mi Supponiamo che tu voglia approfittare del fatto che le informazioni associate al thread logico verranno propagate ai thread secondari invece di volere un posto "thread safe" per archiviare informazioni.Quindi, se dovessi impostare (pr Push) l'AmbientActivity nell'avvio dell'app e quindi non eseguire altre attività, anche i thread successivi faranno parte della stessa attività poiché i dati memorizzati tramite LogicalSetData vengono ereditati dai thread secondari.

Se nel frattempo hai imparato qualcosa da quando hai posto questa domanda, sarei molto interessato a sentirlo. Anche se non l'avessi fatto, sarei interessato a sapere cosa stai facendo con il contesto.

Al momento, sto lavorando per mantenere alcune informazioni di contesto per la registrazione/traccia (simile al supporto del contesto Trace.CorrelationManager.ActivityId e Trace.CorrelationManager.LogicalOpertionStack e log4net/NLog). Vorrei salvare alcuni contesti (app corrente, istanza corrente dell'app, attività corrente (magari annidata)) da utilizzare in un'app o in un servizio WCF E voglio propagarlo "automaticamente" tra i confini del servizio WCF. Questo per consentire che le dichiarazioni di registrazione registrate in un repository centrale siano correlate per client/attività/ecc. Saremmo in grado di eseguire query e correlare per tutte le dichiarazioni di registrazione da un'istanza specifica di un'applicazione specifica. Le istruzioni di registrazione potrebbero essere state generate sul client o in uno o più servizi WCF.

La propagazione di ActivityId in WCF non è necessariamente sufficiente per noi perché vogliamo propagare (o pensiamo che lo facciamo) più che solo l'ActivityId. Inoltre, vogliamo propagare queste informazioni dai client Silverlight ai servizi WCF e Trace.CorrelationManager non è disponibile in Silverlight (almeno non in 4.0, forse qualcosa di simile sarà disponibile in futuro).

Attualmente sto prototipando la propagazione delle nostre informazioni sul "contesto" usando IClientMessageInspector e IDispatchMessageInspector. Sembra che probabilmente funzionerà bene per noi.

Per quanto riguarda la dipendenza da System.Web, l'implementazione di NHibernate ha un "ReflectiveHttpContext" che utilizza la reflection per accedere a HttpContext in modo che non ci sia una dipendenza di progetto su System.Web. Ovviamente, System.Web dovrebbe essere disponibile dove viene distribuita l'app se HttpContext è configurato per essere utilizzato.

Problemi correlati