有什么办法来处理ASMX服务的asynchronous/等待?

我有一个Web应用程序,为JSON和ASMX Web服务提供WCF REST API。 该应用程序已经存在了几年。 它基于ASP.NET 2.0,但几年前升级到.NET 4.0,而我刚刚升级到.NET 4.5,以便能够使用新的asynchronous框架。

应用程序背后是一些传统服务,我意识到通过asynchronous提高性能有很大的潜力。 我已经通过应用程序实现了asynchronous,并且通过WCF REST API,一切都可以正常工作。

太迟了,我发现ASMX API失败,我想这样的方法:

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

然后我知道ASMX不支持async / await,大家build议迁移到WCF。 我对此不太高兴。 ASMX(实际上是其中的三个)被填充了不同的方法,并且有大量的API消费者,我们希望继续从旧API提供服务。

但是我们需要提高性能! 有谁知道一个解决方法,所以我可以继续使用ASMX后面的asynchronous/等待,但像以前一样公开ASMX?

有可能做到这一点,但会有点尴尬。 ASMX支持APM风格的asynchronous方法 ,您可以将TAP转换为APM (但请注意,该页上的MSDN示例不会正确传播exception)。

我在我的博客上有一个例子,展示了如何在APM中封装TAP实现 (exception传播保持正确的exceptiontypes,但是丢失了堆栈;请参阅ExceptionDispatchInfo以获得完全正确的exception传播)。 当WCF仅支持APM时,我使用了这一段时间。 一个非常类似的方法应该为ASMX工作。

但是,请注意,您将不得不4.5目标(即, httpRuntime.targetFrameworkasync / await按预期工作 。

如果你的问题只是简单地把asynchronous逻辑的顶部集成到你的asmx中,你可以像下面的代码片段那样做。

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

请注意,如果Trip.GetTrip()抛出一个exception,您将收到一个AggregateException,而不是在等待抛出exception时收到的exception。 你可以做

 [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(); } }