通过重建AsynchResult对象来模拟推送技术 - 它甚至可能吗?

时间:2010-12-06 21:11:28

标签: c# asynchronous push iasyncresult ihttpasynchandler

最近,我使用HttpAsyncHandler成功创建了一个长轮询服务。在开发期间,它来到我(那)我“可能”能够多次重复使用AsyncResult对象而无需长时间轮询。如果可能的话,我可以通过重新构建或重新使用AsyncResult来“模拟”推送技术(将第一个请求视为订阅请求)。

当然,第一个调用很有效,但后续调用一直给我“对象未设置为对象的实例”。我在“猜测”这是因为某些对象是静态的,因此,一旦“完成”无法重复使用或检索(任何洞察力都会很棒!)。

所以问题是......

是否可以从旧回调中动态构建新的回调?

最初的“订阅”流程如下:

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);
}

2 个答案:

答案 0 :(得分:4)

IAsyncResult实现必须满足certain invariants,其中之一是它只能完成一次。你没有确定你正在使用的AsyncResult,但如果它是Richter's famous version,那么它会支持这种不变量。

如果您不想遇到实施event-based asynchronous pattern的麻烦,那么最好的选择是Microsoft Rx,这是一个真正的基于推送的系统。

答案 1 :(得分:0)

首先我要说的是我完全不熟悉IHttpAsyncHandler接口和用法。

话虽如此,通常在使用异步编程模型时,每个AsyncResult都代表一个特定的异步方法调用,不应该重用。看起来你正在寻找一个RegisterEvent(回调)方法而不是BeginProcessing(回调方法) - 所以即使你能够让它工作,设计也不能用异步编程最佳实践(恕我直言)。

我认为既然你使用的是基于请求/响应的http,你似乎不太可能为一个请求推送多个响应,即使你能够以某种方式破解它,你的客户最终会得到因未答复的请求而导致超时,这对您的目标而言会有问题。

我知道在Remoting中你可以注册远程事件,而WCF支持双工合同,如果这是你的选择,可以启用“推送技术”。

祝你好运。