Domanda

Di recente, ho creato con successo un servizio a lungo polling utilizzando HttpAsyncHandler di. Durante lo sviluppo è venuto da me (che) ho “potrebbe” essere in grado di ri-utilizzare l'oggetto AsyncResult molte volte senza a lungo polling ripetutamente. Se possibile, quindi ho potuto “simulare” push-tecnologia da parte ri-costruzione o ri-utilizzando l'AsyncResult in qualche modo (trattando la prima richiesta, come se si trattasse di un abbonamento richiesta).

Naturalmente, la prima chiamata grandi opere, ma le chiamate successive a mantenere avermi dato “oggetto non impostato su un'istanza di un oggetto”. Io sono “indovinare”, è perché alcuni oggetti sono statici, e quindi, una volta "completato" non possono essere riutilizzati o recuperati (tutta la comprensione ci sarebbe impressionante!).

Quindi la domanda è ...

E 'possibile creare dinamicamente una nuova richiamata dal vecchio richiamata?

Il processo iniziale "abbonamento" va in questo modo:

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

Ecco un esempio di ciò che il servizio fa:

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

Ecco un esempio di ciò che il () chiamata AsyncResult.ProcessRequest fa:

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

SO ... sarebbe qualcosa come questo sia possibile?
Ho letteralmente provato questo e non ha funzionato ... ma è qualcosa di "mi piace" è possibile?

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

if(request.ProcessRequest(message))
{
     _subscribers.Remove(request);
     Subscribers.Add(newRequest);
}
È stato utile?

Soluzione

implementazioni IAsyncResult devono soddisfare alcune invarianti , uno dei quali è che può essere completata solo una volta. Non identificare il AsyncResult si sta utilizzando, ma se è famosa versione di Richter , allora sarebbe sostenere che invariante.

Se non si vuole passare attraverso la briga di attuare la event- basato modello asincrono , quindi l'opzione migliore è Microsoft Rx , che è un vero e proprio sistema push-based.

Altri suggerimenti

Lasciatemi prima prefazione di dicendo che sono completamente familiarità con l'interfaccia e l'uso di IHttpAsyncHandler.

Detto, in generale quando si utilizza un modello di programmazione asincrona, ciascuna AsyncResult rappresenta un metodo specifico chiamata asincrona e non deve essere riutilizzato. Sembra che si sta cercando di più per un metodo di RegisterEvent (callback) di un (metodo di callback) BeginProcessing -. Quindi, anche se sono stati in grado di ottenere questo al lavoro, il design non regge da asynchonous migliori pratiche di programmazione (secondo me)

Suppongo che, dal momento che si sta utilizzando http che è richiesta / risposta basata, sembra improbabile che si sarà in grado di spingere le risposte multiple per una richiesta e anche se tu fossi in grado di incidere in qualche modo questo in su, il vostro cliente finirà per ottenere un timeout a causa della sua richiesta senza risposta, che sarebbe problematico per quello che si sta andando per.

Lo so in Remoting è possibile registrarsi per gli eventi remoti e WCF supporta contratti duplex che può consentire "tecnologia push" se questa è un'opzione per voi.

In bocca al lupo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top