1

の実装について説明しているこのアリクルを見ましたIHttpAsyncHandler

この部分を見てください:

public class MyAsyncHandler : IHttpAsyncHandler
{
    /// 
    /// The queue holds a list of asynchronous results
    /// with information about registered sessions
    /// 
    public static List<myasyncresult> Queue;


    static MyAsyncHandler()
    {
        // Initialize the queue
        Queue = new List<myasyncresult>();
    }



    public IAsyncResult BeginProcessRequest(HttpContext context, 
                        AsyncCallback cb, object extraData)
    {
        // Fetch the session id from the request
        var sessionId   = context.Request["sessionId"];

        // Check if the session is already registered
        if (Queue.Find(q => q.SessionId == sessionId) != null)
        {
            var index = Queue.IndexOf(Queue.Find(q => q.SessionId == sessionId));

            // The session has already been registered,
            // just refresh the HttpContext and the AsyncCallback
            Queue[index].Context  = context;
            Queue[index].Callback = cb;

            return Queue[index];
        }

        // Create a new AsyncResult that holds the information about the session
        var asyncResult = new MyAsyncResult(context, cb, sessionId);

        // This session has not been registered yet, add it to the queue
        Queue.Add(asyncResult);

        return asyncResult;
    }

    public void EndProcessRequest(IAsyncResult result)
    {
        var rslt  = (MyAsyncResult) result;

        // send the message to the recipient using
        // the recipients HttpContext.Response object
        rslt.Context.Response.Write(rslt.Message);

        // reset the message object
        rslt.Message = string.Empty;
    }


}

ここで非同期部分はどこにありますか?ここにBeginXXXメソッドはありません。

またThread.CurrentThread.IsThreadPoolThread、の最初の行で 確認したところ、表示されBeginProcessRequestましたTRUE

では、この例の非同期部分はどこにありますか?

4

1 に答える 1

2

このハンドラーはリクエストを受信すると、を呼び出しますBeginProcessRequest。呼び出し元のスレッドをブロックしません。

処理が完了すると、が呼び出されますEndProcessRequest

これにより、asp.netワーカープロセススレッドは、処理中に他の要求を処理できるようになります。がEndProcessRequest呼び出されると、処理された結果をクライアントに送り返すことができます。

asp.netが非同期リクエストのライフサイクル中にスレッドを管理する方法についての多くの説明があります。

非同期ページの存続期間中、コンテキストはASP.NETスレッドプールからの1つのスレッドから始まります。非同期リクエストが開始された後、コンテキストにはスレッドが含まれません。非同期要求が完了すると、完了ルーチンを実行しているスレッドプールスレッドがコンテキストに入ります。これらは、要求を開始したスレッドと同じである可能性がありますが、操作の完了時にたまたま空いているスレッドである可能性が高くなります。

同じアプリケーションに対して複数の操作が同時に完了する場合、AspNetSynchronizationContextは、それらが一度に1つずつ実行されることを保証します。これらはどのスレッドでも実行できますが、そのスレッドには元のページのIDとカルチャがあります。

非同期をいつ使用するかについてのいくつかの理由:

非同期ハンドラーがあると、他の非同期ステップを使用できる場合にのみ役立ちます(オフボックスのデータベース呼び出しや、非同期を呼び出すこともできる長いハードドライブの読み取りなど)。これを適切に行うには、非同期をチェーンします。メソッド(つまり、BeginProcessRequestは同じ(または個別の)コールバックでFileStream.BeginReadを呼び出し、それに応じて処理します。)ここを参照してください:http: //msdn.microsoft.com/en-us/library/system.web.ihttpasynchandler.aspx

非同期ハンドラーの使用方法に関するこの非常に詳細な説明をご覧ください

真に効果的な非同期ハンドラーを構築するには、BeginProcessRequestに応答して手動で追加のスレッドを生成する必要があります。非同期ハンドラーを成功させるには、3つの重要な側面があります。まず、BeginProcessRequestから返されるIAsyncResultをサポートするクラスを作成します。次に、スレッドを生成して、リクエスト処理を非同期で実行します。最後に、要求の処理が終了し、応答を返す準備ができていることをASP.NETに通知します。

要約すると、処理スレッドを作成していない場合、または長時間待機している場合、非同期ハンドラーはあまり効果がありません。待機中、リクエストにはスレッドが関連付けられていません。これにより、長時間待機しているタスクでもasp.netを適切に拡張できます。

于 2012-06-11T07:58:18.620 に答える