C# 在ASMX服务后面是否有处理异步/等待的方法?

C# 在ASMX服务后面是否有处理异步/等待的方法?,c#,wcf,web-services,asynchronous,asmx,C#,Wcf,Web Services,Asynchronous,Asmx,我有一个web应用程序,为JSON提供WCF REST API和ASMX web服务。这个应用程序已经存在好几年了。它基于ASP.NET 2.0,但几年前升级到了.NET 4.0,我刚刚升级到.NET 4.5,以便能够使用新的异步框架 应用程序背后是一些遗留服务,我意识到通过异步提高性能有很大的潜力。我在整个应用程序中都实现了异步,通过WCF REST API,一切都可以完美地工作 太晚了,我发现ASMX API失败了,我想要这样的方法: [WebMethod(Description = "Ta

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

应用程序背后是一些遗留服务,我意识到通过异步提高性能有很大的潜力。我在整个应用程序中都实现了异步,通过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;
}
[WebMethod(Description=“将内部行程ID作为参数”)]
异步公共任务GetTrip(int-tripid)
{
var t=等待Trip.GetTrip(tripid);
返回t;
}
然后我了解到async/await在ASMX中根本不受支持,每个人都建议迁移到WCF。我对此不太高兴。ASMX(实际上是其中的三个)中填充了不同的方法,我们希望从旧API中继续提供大量API使用者


但是我们需要提高性能!是否有人知道一种变通方法,以便我可以继续在ASMX后面使用async/Wait,但像以前一样公开ASMX?

这样做可能是可行的,但会有点尴尬,您可以(但是,请注意,该页面上的MSDN示例没有正确传播异常)

我在我的博客上有一个例子,显示了(异常传播保持了正确的异常类型,但丢失了堆栈;有关完全正确的异常传播,请参阅)。当WCF只支持APM时,我使用了一段时间。对于ASMX,应该采用非常类似的方法


但是,请注意,您会这样做。

如果您的问题只是将异步逻辑的顶部集成到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()引发异常,您将收到一个AggregateException,而不是等待引发异常时您将收到的异常。你能行

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

您可能无法使ASMX服务本身以异步方式运行,但如果您使用javascript从WebApp调用,则可以在调用时围绕服务包装一个承诺,以便在客户端利用异步

如上所述,它不会使您的服务异步,但它是在客户端内以异步方式使用此服务的一个示例(即,在本实例中使用javascript承诺来停止进一步的操作,直到服务解决为止。类似地,可以调整它以继续操作,并在解决或失败后执行其他操作)

优化服务本身只是解决方案的一半,另一半在客户机内部,因此我认为这对某些人来说是一个有益的扩展:)

Javascript代码:

var tripObj;

async function getTripObject(tripId) {


  // Ensures Trip is fetched before proceeding 
  var promise = new Promise(function (resolve, reject) {
    ASMXService.getTrip(tripId, async function (ret) {
      tripObj = ret;

      resolve("Success");
    }, function () {
      reject("Error");
    });
  });

  await promise;

}

您知道异步只有在特殊情况下才会更快吗?很可能会慢一点。首先研究一下这个。使用.Wait()的可能重复会导致WebMethod阻塞,从一开始就否定了异步的任何好处。嗨,Stephen,将EAP包装到任务中会是一个伪异步吗?e、 g.正如您所建议的@HarisMunawar:No.“伪异步”是为了提供异步API而阻塞线程池线程。EAP是异步的,因此没有线程池线程被阻塞。