2013-09-04 5 views
13

Ho un'app Web che serve un'API REST WCF per JSON e un servizio Web ASMX. L'applicazione è in circolazione da alcuni anni. È basato su ASP.NET 2.0, ma aggiornato a .NET 4.0 un paio di anni fa, e ho appena aggiornato a .NET 4.5 per poter usare il nuovo framework asincrono.C'è un modo per gestire asincroni/attese dietro un servizio ASMX?

Dietro l'applicazione ci sono alcuni servizi legacy, e ho capito che c'è un grande potenziale per aumentare le prestazioni andando asincrono. Ho implementato async completamente attraverso l'applicazione, e tutto funziona perfettamente attraverso l'API REST WCF.

Troppo tardi ho scoperto che l'API ASMX non riesce, ho voluto metodi come questo:

[WebMethod(Description = "Takes an internal trip ID as parameter.")] 
async public Task<Trip> GetTrip(int tripid) 
{ 
    var t = await Trip.GetTrip(tripid); 
    return t; 
} 

Poi ho imparato che asincrone/attendono non è supportato in ASMX a tutti, e ognuno consiglia di migrare a WCF . Non sono troppo contento di questo. L'ASMX (in realtà tre di questi) sono pieni di metodi diversi e ci sono un sacco di utenti API che vogliamo continuare a servire dalla vecchia API.

Ma abbiamo bisogno dell'aumento delle prestazioni! Qualcuno sa di una soluzione alternativa, quindi posso continuare a utilizzare async/attendere dietro ASMX, ma esporre ASMX come prima?

+1

Hai capito che async è più veloce solo in circostanze particolari? Potrebbe essere più lento. Ricerca questo prima. – usr

+0

possibile duplicato di [Calling Task-based methods from ASMX] (http://stackoverflow.com/questions/24078621/calling-task-based-methods-from-asmx) – Paddy

risposta

13

Potrebbe essere possibile farlo, ma sarebbe un po 'imbarazzante. ASMX supports APM-style asynchronous methods, ed è possibile convert TAP to APM (tuttavia, si noti che l'esempio MSDN su quella pagina non propagano correttamente le eccezioni).

Ho un esempio sul mio blog che mostra how to wrap TAP implementations in APM (con propagazione delle eccezioni che mantiene il tipo di eccezione corretto ma perde lo stack, vedere ExceptionDispatchInfo per propagazione delle eccezioni completamente corretta). L'ho usato per un po 'quando WCF supportava solo l'APM. Un approccio molto simile dovrebbe funzionare per ASMX.

Tuttavia, si noti che sarà have to target 4.5 (i.e., httpRuntime.targetFramework) for async/await to work as expected.

2

Se il tuo problema è semplicemente l'integrazione della parte superiore della tua logica asincrona nel tuo asmx, puoi fare come il seguente frammento.

[WebMethod(Description = "Takes an internal trip ID as parameter.")] 
public Trip GetTrip(int tripid) { 
    var trip = Trip.GetTrip(tripid).Wait(); 
    return trip; 
} 

essere consapevoli che se Trip.GetTrip() genera un'eccezione, si riceverà un'AggregateException, e non l'eccezione che avrebbe ricevuto se fosse attendono gettare l'eccezione. Puoi fare

[WebMethod(Description = "Takes an internal trip ID as parameter.")] 
public Trip GetTrip(int tripid) { 
    try 
    { 
    var trip = Trip.GetTrip(tripid).Wait(); 
    return trip; 
    } 
    catch(AggregateException ex) 
    { 
    throw ex.InnerException.First(); 
    }  
} 
+9

utilizzando .Wait() causerà il blocco del WebMethod In primo luogo, annullando qualsiasi vantaggio di essere asincroni. –

Problemi correlati