Matt Dawdy
Matt Dawdy

Reputation: 19707

Keep processing after returning a response to the client

I've got a generic handler (.ashx) page that receives an XML document from a lead provider. I then take that XML document and send it on to a third party for underwriting. I wait for a response from the 3rd party, then I pass that response along to the lead provider. All of this happens in 30 seconds or less.

My problem is that the lead provider will only wait for a maximum of 30 seconds before closing the connection and moving on. I am trying to start an internal timer, and if I haven't heard back from the 3rd party underwriter, send a response to the lead provider anyway. This all works fine.

What I want to do is to send the response back to the lead provider, but continue waiting for the 3rd party underwriter's response. They will get it to us...but it might take a couple minutes sometimes.

I've tried all sorts of combinations of

Response.Flush();
Response.Close();
Response.End();
context.ApplicationInstance.CompleteRequest();

All I've gotten that to do is to a) throw an error about thread being aborted, or "Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.", or b) the client thinks that the request was just terminated and it never received the response.

I can't implement a queue type architecture without reworking much of the logic, and even then I don't want to do that because it would increase the processing time of the response.

Any suggestions? It appears that .Close() and .End() are not meant to function how I think they are, and I can't figure out what should be used instead.

Upvotes: 4

Views: 2199

Answers (1)

Steve B
Steve B

Reputation: 37660

Maybe System.Threading.ThreadPool.QueueUserWorkitem() can help you ?

The idea is to queue an operation that will run whenever a thread is free in the threadpool.

public class Data {
    public int ID {get; set; }
    public string OtherData { get; set; }    
}

public override void ProcessRequest(HttpContext context)
{
    var workLoad = new Data {
        ID = int.Parse(context.Request.Params["ID"]),
        OtherData = context.Request.Params["OtherData"]
    };
    // somewhere before the end :
    ThreadPool.QueueUserWorkItem(new WaitCallback(LongRunningMethod), workLoad);

    Response.Flush();
    Response.Close();
}

public void LongRunningMethod(object state) 
{
    var data = (Data)state;
    CalculateTheOriginOfTheLife(data.ID, data.OtherData);
}

Upvotes: 3

Related Questions