2

最近、HttpAsyncHandlerを使用してロングポーリングサービスを正常に作成しました。開発中に、繰り返し長いポーリングを行わなくても、AsyncResultオブジェクトを何度も再利用できる可能性があります。可能であれば、AsyncResultを何らかの方法で再構築または再利用することで、プッシュテクノロジーを「シミュレート」することができます(最初のリクエストをサブスクリプションリクエストであるかのように扱います)。

もちろん、最初の呼び出しはうまく機能しますが、その後の呼び出しでは「オブジェクトがオブジェクトのインスタンスに設定されていません」というメッセージが表示され続けます。私が「推測」しているのは、特定のオブジェクトが静的であるため、「完了」すると再利用または取得できないためです(洞察があれば素晴らしいです!)。

だから問題は…</p>

古いコールバックから新しいコールバックを動的に構築することは可能ですか?

最初の「サブスクリプション」プロセスは次のようになります。

public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
    Guid id = new Guid(context.Request["Key"]);
    AsyncResult request = new AsyncResult(cb, context, id);
    Service.Singleton.Subscribe(request);

    return request;
}

サービスの機能の例を次に示します。

private void MainLoop()
{
    while (true)
    {
        if (_subscribers.Count == 0)
        {
            if (_messages.Count == max)
                _messages.Clear();
        }
        else
        {
            if (_messages.Count > 0)
            {
                Message message = _messages.Dequeue();

                foreach (AsyncResult request in _subscribers.ToArray())
                {
                     if(request.ProcessRequest(message));
                        _subscribers.Remove(request);
                }
            }  
        }

        Thread.Sleep(500);
    }
}

AsyncResult.ProcessRequest()呼び出しの例を次に示します。

public bool ProcessRequest(Message message)
{
    try
    {
        this.Response = DoSomethingUseful(message);
        this.Response.SessionValid = true;
    }
    catch (Exception ex)
    {
        this.Response = new Response();
        this.Response.SessionValid = false;
    }

    this.IsCompleted = true;
    _asyncCallback(this);

    return this.IsCompleted;
}

だから...このような何かが可能でしょうか?
私は文字通りこれを試しましたが、うまくいきませんでした...しかし、何かが「好き」なことは可能ですか?

AsyncResult newRequest = new AsyncResult(request.cb, request.context, request.id);

if(request.ProcessRequest(message))
{
     _subscribers.Remove(request);
     Subscribers.Add(newRequest);
}
4

2 に答える 2

4

IAsyncResult実装は特定の不変条件を満たさなければなりません。その1つは、一度しか完了できないということです。使用しているものを特定することはできませんAsyncResultが、それがリヒターの有名なバージョンである場合、それはその不変条件を支持します。

イベントベースの非同期パターンを実装する手間をかけたくない場合は、真のプッシュベースのシステムであるMicrosoftRxが最適なオプションです。

于 2010-12-07T04:00:00.280 に答える
0

最初に、IHttpAsyncHandlerのインターフェイスと使用法に完全に慣れていないことを説明します。

とはいえ、一般に、非同期プログラミングモデルを使用する場合、各AsyncResultは特定の非同期メソッド呼び出しを表すため、再利用しないでください。BeginProcessing(callbackメソッド)よりもRegisterEvent(callback)メソッドを探しているようです。したがって、これを機能させることができたとしても、非同期プログラミングのベストプラクティス(IMHO)では設計が維持されません。

リクエスト/レスポンスベースのhttpを使用しているため、1つのリクエストに対して複数のレスポンスをプッシュできる可能性は低く、何らかの方法でこれをハックできたとしても、クライアントは最終的にタイムアウトになると思います。あなたが何をしようとしているのか問題になるであろうその未回答の要求に。

Remotingでリモートイベントに登録でき、WCFは、これがオプションである場合に「プッシュテクノロジー」を有効にできる二重契約をサポートしていることを知っています。

幸運を。

于 2010-12-06T22:32:21.490 に答える