2009-12-21 15 views
5

Possiedo un'applicazione Web che fa molto affidamento sui servizi Web. Tutto con i servizi viene eseguito in modo asincrono e con AddOnPreRequestHandlerExecuteAsync. Ad ogni modo, la maggior parte delle mie chiamate funziona bene, ma alcune stanno ritornando dalle loro chiamate di servizio asincrone per trovare un oggetto HttpContext.Current.Response/Request null in endprerequest, che ovviamente si verifica nell'istante in cui provo ad usarlo. Entrambi gli oggetti (Risposta e Richiesta sono disponibili/non nulli all'avvio della richiesta di chiamate non riuscite e funzionano alla fine del premio di altre chiamate).HttpWebRequests asincroni e null HttpContext.Current.Response/Richiesta oggetto

Chiunque si imbatta in qualcosa di simile o ha una supposizione su quale potrebbe essere il problema?

Aggiornamento: sembra aver trovato una soluzione, se creo una variabile per HttpApplication su Init (del HttpModule si verifica tutto in) è possibile accedere a HttpContext da tale variabile.

Aggiornamento: passare HttpApplication o HttpContext.Current sulla funzione begin ha lo stesso problema. Quando vengono passati come parte dello "stato" della chiamata asincrona, finiscono nulli nella funzione finale, anche se sono validi nella funzione di inizio.

Aggiornamento: ho aggiunto alcune registrazioni e ho riscontrato che la chiamata asincrona che sto facendo sta ritornando correttamente, i risultati ci sono, la funzione di callback è invocata correttamente.

risposta

0

Sembra aver trovato una soluzione, se creo una variabile per HttpApplication su Init (del HttpModule si verifica tutto in) è possibile accedere a HttpContext da tale variabile.

+0

Puoi descrivere con dettagli come hai risolto il problema – omoto

+0

Nel mio HttpModule ho una variabile di tipo HttpApplication. Nella chiamata alla funzione init() imposto questa variabile all'HttpApplication che viene passata a init. In BeginPreRequestHandlerExecute e EndPreRequestHandlerExecute mi riferisco all'attuale HttpContext utilizzando oApplication.Context, oApplication è il nome della variabile HttpApplication nel mio HttpModule. – aepheus

5

Sospetto di conoscere il problema che stai incontrando. La risposta, quasi certamente, è quella di sostituire l'uso di HttpWebRequest con WebClient e di utilizzare i metodi * Async di WebClient.

Ecco la lunga spiegazione: ci sono due modelli di programmazione Async totalmente diversi: lo IAsyncResult Async Pattern e lo Event-based Asynchronous Pattern. Il pattern IAsyncResult utilizza i metodi BeginXXX e EndXXX, utilizza le istanze IAsyncResult, utilizza i delegati per i callback e supporta l'attesa del completamento. Il pattern basato sugli eventi utilizza i metodi XXXAsync per avviare azioni asincrone, utilizza eventi XXXCompleted anziché callback per gestire il completamento e (questo è importante per il tuo caso) trasferisce il contesto specifico del thread in ogni gestore di eventi di callback.

In altre parole, se si inserisce il codice di richiamata all'interno di un gestore eventi XXXCompletato (ad esempio WebClient.DownloadStringCompleted), HttpContext.Current verrà popolato correttamente.

Se, tuttavia, si utilizza un metodo BeginXXX (come HttpWebRequest.BeginGetResponse) e un callback delegato, la richiamata verrà eseguita nel contesto di un thread che non garantisce di avere il contesto ASP.NET corretto collegato.

In genere, le classi di libreria .NET Framework utilizzano uno schema asincrono o l'altro. In genere, le classi di livello inferiore (ad esempio HttpWebRequest) utilizzeranno il modello IAsyncResult, mentre le classi di livello superiore (ad esempio WebClient) utilizzeranno il modello basato sugli eventi. Alcune classi di oddball (ad esempio proxy .NET remoti generati automaticamente) supporteranno entrambi i pattern, ma questa è una rarità.

Quindi, se è facile da fare, suggerirei di passare a WebClient e gestori di eventi invece di HttpWebRequest e delegati di richiamata. Questo dovrebbe risolvere il tuo problema. Se passare a WebClient è troppo difficile, commentare e io probabilmente posso suggerire alcune alternative più oscure.

+0

Non sono sicuro di quanto sarebbe stato facile implementarlo nel mio caso.Credo di essere legato al pattern IAsyncResult almeno al livello base perché questo è il pattern supportato da AddOnPreRequestHandlerExecuteAsync. E, dato che attualmente ho cose che funzionano semplicemente salvando lo stato in una variabile, preferirei non scherzare. – aepheus