1

HttpModuleWeb サイトに送信されるすべてのリクエストをログに記録する非同期を作成しました。要求が Web サイトに到着すると、カスタム http モジュールが WebAPI を呼び出して、情報をデータベースに記録します。IIS Express を使用した .Net 4.5/Visual Studio。

////////////Custom HTTP module////////////////////
public class MyHttpLogger : IHttpModule
{
      public void Init(HttpApplication httpApplication)
      {
          EventHandlerTaskAsyncHelper taskAsyncHelper = new EventHandlerTaskAsyncHelper(LogMessage);
          httpApplication.AddOnBeginRequestAsync(taskAsyncHelper.BeginEventHandler, taskAsyncHelper.EndEventHandler);
      }

      private async Task LogMessage(object sender, EventArgs e)
      {
        var app = (HttpApplication)sender;
        var ctx = app.Context;

        //use default credentials aka Windows Credentials
        HttpClientHandler handler = new HttpClientHandler()
        {
            UseDefaultCredentials = true
        };

        using (var client = new HttpClient(handler))
        {
            client.BaseAddress = new Uri("http://localhost:58836/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var actvity = new Activities() { AppId = "TEST123", ActivityId = 10, CreatedBy = 1 };
            await client.PostAsJsonAsync("api/activity", actvity);
        }
    }

「api/activity」の簡略化された WebAPI コード。

public async Task<HttpResponseMessage>Post(Activities activity)    
{
         await Task.Delay(30000);
         // Database logging code goes here….
        return new HttpResponseMessage(HttpStatusCode.Created);
}

問題は、PostAsJsonAsyncが実行されると、コードがそこで停止することです。コードは待機する必要があるため、これは正しいことです。しかし、呼び出しルーチンが期待どおりに非同期に続行されず、Web サイトの応答が 30 秒遅くなります。

このコードの何が問題になっていますか? 非同期をフックしてHttpModuleも、Http アプリケーションのフローに干渉してはいけませんか? 現在、ウェブサイトにアクセスすると、コードがブロックされています。

4

1 に答える 1

1

ここで、HTTP リクエストとローカル アプリケーションの違いを理解する必要があります。HTTP は完全にステートレスです。基本的に、リクエストを送信すると、サーバーがそれを処理してレスポンスを返します。サーバーはクライアントに関する状態情報を保持していません。クライアントが誰であるかはまったくわかりません。したがって、あなたの場合、ブラウザはリクエストを送信します->サーバーはそれを取得し、それを処理するために30秒待ってから結果を返します->ブラウザは応答を取得し、これがブラウザが結果を表示するポイントです。あなたがやろうとしているのは、ブラウザがリクエストを送信し、ブラウザが何かを表示することを期待し、30秒後にサーバーが処理を終了し、何か他のものを表示したいということです。上記の理由により、これは await では実行できません。

于 2014-11-05T19:54:09.047 に答える