web-dev-qa-db-ja.com

ASMXサービスの背後で非同期/待機を処理する方法はありますか?

WCF REST API forJSONおよびASMXWebサービスを提供するWebアプリがあります。このアプリケーションは数年前から存在しています。ASP.NET2.0に基づいていますが、.NETにアップグレードされています。数年前の4.0で、新しい非同期フレームワークを使用できるように.NET4.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;
}

その後、ASMXではasync/awaitがまったくサポートされていないことを知り、誰もがWCFに移行することをお勧めします。私はこれについてあまり嬉しくありません。 ASMX(実際には3つ)にはさまざまなメソッドが詰め込まれており、古いAPIから提供し続けたいAPIコンシューマーがたくさんあります。

ただし、パフォーマンスを向上させる必要があります。 ASMXの背後でasync/awaitを使い続けることができるように、回避策について誰かが知っていますが、以前のようにASMXを公開しますか?

20
Barslett

これを行うことは可能かもしれませんが、それは少し厄介でしょう。 ASMXはAPMスタイルの非同期メソッド をサポートしており、TAPをAPMに 変換できます (ただし、そのページのMSDNの例では例外が正しく伝播されないことに注意してください)。

私のブログには、 TAP実装をAPM でラップする方法を示す例があります(正しい例外タイプを保持するがスタックを失う例外伝播を使用します。を参照してください。 ExceptionDispatchInfo 完全に正しい例外伝播の場合)。 WCFがAPMのみをサポートしていたときに、これをしばらく使用しました。 ASMXでも非常によく似たアプローチが機能するはずです。

ただし、 4.5をターゲットにする必要があることに注意してください(つまり、httpRuntime.targetFrameworkasync/awaitが期待どおりに機能するため

15
Stephen Cleary

ASMXサービス自体を非同期で動作させることはできないかもしれませんが、JavaScriptを使用してWebAppから呼び出す場合は、クライアント側で非同期を利用するために、呼び出すときにサービスをpromiseでラップできます。

述べたように、それはあなたのサービスを非同期にしませんが、クライアント内で非同期の方法でこのサービスを使用する例です(つまり、このインスタンスでは、サービスが解決されるまでそれ以上の操作を停止するためにjavascriptpromiseが使用されます。解決または失敗したら、操作を続行し、他のアクションを実行するように調整します)。

サービス自体の最適化はソリューションの半分にすぎず、残りの半分はクライアント内にあるため、これは一部のユーザーにとって役立つ拡張になると思いました:)

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;

}
0
Radderz