2013-10-10 12 views
16

Sto revisionando un servizio WCF. Nell'intestazione di ogni messaggio si inseriscono i dati che il servizio utilizzerà in seguito per creare una stringa di connessione in un DB. Questo perché il servizio verrà utilizzato da numerosi siti diversi, ciascuno con il proprio DB che il servizio deve interrogare. Utilizziamo l'estensibilità wcf. Abbiamo un MessageInspector personalizzato che, dopo aver ricevuto la richiesta, estrae i dati dall'intestazione del messaggio, crea un contesto (che implementa IExtension) e lo aggiunge a OperationContext.Current.Extensions. Prima di inviare la risposta, il contesto personalizzato viene rimosso dalla raccolta Extencions.WCF Operation.Context not Thread safe?

Questo è un modello abbastanza comune, come discusso qui:

Where to store data for current WCF call? Is ThreadStatic safe?

e qui:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/319cac66-66e8-4dfe-9a82-dfd289c9df1f/wcf-doesnt-have-session-storage-so-where-should-one-store-call-specific-data?forum=wcf

Questo tutto funziona bene fino a quando il servizio riceve una richiesta, processi invia la risposta e riceve la richiesta successiva. E se il servizio riceve una richiesta e prima di poter rispondere riceve una seconda richiesta? Ho creato una piccola applicazione per console per testarlo. Invio 2 messaggi da 2 thread diversi, ho reso il servizio wcf atteso per 2 secondi, per garantire che la seconda richiesta arrivi prima che il primo sia completato e questo è quello che ottengo:

ID sito: test1450; Sessione: uuid: 2caf47cf-7d46-4d72-9275-d9c037fa0e70; id = 2: ID discussione: 6

ID sito: test1450; Sessione: uuid: 2caf47cf-7d46-4d72-9275-d9c037fa0e70; id = 3: ID discussione: 22

Sembra che wcf crei 2 sessioni in esecuzione su 2 thread diversi, ma ID sito è lo stesso. Non dovrebbe. A giudicare da questo sembra OperationContext.Current.Extensions è una raccolta condivisa tra thread. In questo momento sono incline a pensare che il mio test sia sbagliato e mi sono perso qualcosa.

Qualcuno ha provato qualcosa di simile e ha scoperto che OperationContext.Current non è thread-safe?

risposta

11

OperationContext.Current come altre proprietà simili come HttpContext.Current hanno valori affini (o thread statici). Quindi sono thread-safe nel senso che più thread possono leggerli, ma thread diversi avranno istanze diverse. Possono essere pensati come dizionari tra thread e istanze specifici.

Quindi in questo contesto sono non thread safe.

Le richieste vengono gestite da un pool di thread in modo che le richieste simultanee abbiano ID di thread diversi. (fino a un punto in cui il pool di thread è pieno, quindi le richieste verranno messe in attesa)

+0

Se questo è il caso, non riesco ancora a capire perché ottengo lo stesso ID sito. Se ogni thread dovesse ottenere dati diversi, suppongo che dovrebbe ottenere l'ID del sito contenuto nel messaggio che sta elaborando. Sembra che il contesto di operazione corrente sia diverso per ogni thread (ID di sessione differente), ma la raccolta di estensioni sembra contenere la stessa istanza del contesto personalizzato. – Hoppers13

+0

Se può essere utile: ho provato a configurare il server in modo diverso: InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single – Hoppers13

+0

Questo è il modo in cui è stato originariamente configurato: InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple.Ma il problema è lo stesso – Hoppers13