2012-06-19 19 views
10

Global.asaxで私のDB上でいくつかの非同期操作を呼び出す必要があります。 たとえばApplication_AuthenticateRequestでDBに対してユーザーを認証する必要があります 非同期タスクでは可能ですか?ASP.NET:Global.asaxで非同期タスクを呼び出すことは可能ですか?

+0

なぜ非同期で認証しますか?それは同期して行われてはいけませんか? – Rich

+1

多くのユーザからのリクエストでは、sychronouseがDBへの呼び出しによって他のリクエスタをキューに入れるため、レスポンス時間が長くなります。 [ASP.NET MVC 4のタスクベース非同期プログラミングモデル(TAP)を使用した非同期データベース呼び出し](http://www.tugberkugurlu.com/archive/asynchronous-database-calls-with-task-based-asynchronous -programming-model-tap-in-asp-net-mvc-4) – user1328761

+2

AuthenticateRequestを非同期に処理することで、スループットを向上させることができました。スレッドがネットワークによってブロックされる必要はありません。 –

答えて

2

新しいC#キーワードasyncとawaitを使用する方法が見つかりませんでしたが、IHttpAsyncHandlerインターフェイスを実装しているため、APMパターンを使用してGlobal.asaxで非同期操作を使用することができます。ここでは、非同期をデモするための小さなコードですが、ここでは例としてWebRequstを使用します。代わりにデータベース操作を使用してください。

public Global() 
    { 
     this.AddOnAuthenticateRequestAsync(BeginGetAsyncData, EndGetAsyncData); 
    } 

    IAsyncResult BeginGetAsyncData(Object src, EventArgs args, AsyncCallback cb, Object state) 
    { 
     Console.WriteLine("BeginGetAsyncData: thread #" + System.Threading.Thread.CurrentThread.ManagedThreadId); 
     WebRequest request = WebRequest.Create("http://www.google.com"); 
     return request.BeginGetResponse(cb, request); // call database async operation like SqlCommand.BeginExecuteReader() 
    } 

    void EndGetAsyncData(IAsyncResult ar) 
    { 
     Console.WriteLine("EndGetAsyncData: thread #" + System.Threading.Thread.CurrentThread.ManagedThreadId); 

     WebRequest requst = (WebRequest)ar.AsyncState; 
     System.Net.WebResponse response = requst.EndGetResponse(ar); // call database async operation like SqlCommand.EndExecuteReader() 

     Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd()); 
     response.Close(); 
    } 
+0

ありがとう! 私は見つけました:) [http://www.codeproject.com/Articles/373479/Writing-asynchronous-HTTP-Module-in-ASP-NET-4-5](http://www.codeproject。 com/Articles/373479/Writing-Asynchronous-HTTP-Module-in-ASP-NET-4-5) – user1328761

1

AuthenticateRequestの非同期バージョンを自分で追加する必要があります。

public MvcApplication() 
{ 
    // Contrary to popular belief, this is called multiple times, one for each 'pipeline' created to handle a request. 
    // Wire up the async authenticate request handler. 
    AddOnAuthenticateRequestAsync(BeginAuthenticateRequest, EndAuthenticateRequest, null); 
} 

問題は新しい非同期を使用してBeginAuthenticateRequestEndAuthenticateRequestを実装する方法、そしてある/ Cの#の機能を待って次のコードを使用します。まずは、邪魔たAuthenticateRequestの私達の非同期バージョンを取得してみましょう:私たちは次に何をする必要がどのような

private async Task AuthenticateRequestAsync(object sender, EventArgs args) 
{ 
    // Yay, let's do async stuff! 
    await ... 
} 

はBeginAuthenticateRequestとEndAuthenticateRequestの実装を思い付くています。私はa blog postに従ったが、私の独自の実装を派生:

private IAsyncResult BeginAuthenticateRequest(object sender, EventArgs args, AsyncCallback callback, object state) 
{ 
    Task task = AuthenticateRequestAsync(sender, args); 
    var tcs = new TaskCompletionSource<bool>(state); 

    task.ContinueWith(_ => 
    { 
     if (task.IsFaulted && task.Exception != null) tcs.TrySetException(task.Exception.InnerExceptions); 
     else if (task.IsCanceled) tcs.TrySetCanceled(); 
     else tcs.TrySetResult(true); 

     if (callback != null) callback(tcs.Task); 
    }, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default); 

    return tcs.Task; 
} 

あなたはそれがどのように動作するかを確認するために全体のリンク先の記事を読むことができますが、基本的にIAsyncResultは、タスクによって実装されているので、あなたがしなければならないすべてが終わったときにコールバックを呼び出すことです。

最後のビットが死んで簡単です。今、これを行うための簡単な方法があります

private void EndAuthenticateRequest(IAsyncResult result) 
{ 
    // Nothing to do here. 
} 
18

:この方法で

public MvcApplication() 
    { 
     var wrapper = new EventHandlerTaskAsyncHelper(DoAsyncWork); 
     this.AddOnAuthenticateRequestAsync(wrapper.BeginEventHandler, wrapper.EndEventHandler); 
    } 

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

     ... 
     await doSomethingAsync(); 
    } 

、あなたは非同期キーワードを使用する方法を定義し、そのメソッドをラップ'EventHandlerTaskAsyncHelper'クラスを使用してBeginEventHandlerおよびEndEventHandlerメソッドを生成し、AddOnAuthenticateRequestAsync呼び出しに渡します。

関連する問題