0
\$\begingroup\$

I have created a .ashx file that is able to handle concurrent http requests.

Works great, but now I'd like to create a base class that does the common work in order to not repeat myself each time I need to create a new .ashx of the same kind.

Here is my current code for the http handler:

public class BaseAsyncHandler : IHttpAsyncHandler, IRequiresSessionState
{
    public bool IsReusable
    {
        get { return false; }
    }

    public BaseAsyncHandler()
    {
    }

    public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
    {
        BaseAsynchOperation asynch = new BaseAsynchOperation(cb, context, extraData);
        asynch.StartAsyncWork();
        return asynch;
    }

    public void EndProcessRequest(IAsyncResult result)
    {
    }

    public void ProcessRequest(HttpContext context)
    {
        throw new InvalidOperationException();
    }
}
public class BaseAsynchOperation : IRequiresSessionState, IAsyncResult
{
    private bool _completed;
    private Object _state;
    private AsyncCallback _callback;
    public HttpContext _httpContext;

    bool IAsyncResult.IsCompleted
    {
        get { return _completed; }
    }

    WaitHandle IAsyncResult.AsyncWaitHandle
    {
        get { return null; }
    }

    Object IAsyncResult.AsyncState
    {
        get { return _state; }
    }

    bool IAsyncResult.CompletedSynchronously
    {
        get { return false; }
    }

    public BaseAsynchOperation(AsyncCallback callback, HttpContext context, Object state)
    {
        _callback = callback;
        _httpContext = context;
        _state = state;
        _completed = false;
    }

    public void StartAsyncWork()
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsyncTask), null);
    }

    protected virtual void OnBeforeStartAsyncTask()
    {  
    }

    public void StartAsyncTask(Object workItemState)
    {
        OnBeforeStartAsyncTask();

        _httpContext.Response.ContentType = "application/json";


        _completed = true;
        _callback(this);
    }
}

My new test that inherits from the base class:

public class TestAsyncHandler : BaseAsyncHandler
{
    public TestAsyncHandler()
    {

    } 
}

public class TestAsyncOperation : BaseAsynchOperation
{
    public TestAsyncOperation(AsyncCallback callback, HttpContext context, object state) : base(callback, context, state)
    {
    }

    protected override void OnBeforeStartAsyncTask()
    {
        var test = _httpContext.Request["test"]; // code never ends up here...
    }
}

Since all my work is done in the StartAsyncTask() method (similar to ProcessRequest() in a regular generic handler .ashx), I thought that I add a method there which can be overridden. However, it never seems to get called.

What did I miss? Do you have any other suggestions on improvments?

\$\endgroup\$
1
\$\begingroup\$

A generic ASP.NET ASHX handler can handle concurrent HTTP requests perfectly fine out of the box. This is partially thanks to the hosting infrastructure and ASP.NET itself. There's no need for all of this. I'm saying this because I'm not sure this is what you really want.

But maybe you're referring to asynchronous handlers which means something else entirely, in which case I'd refer to this: http://msdn.microsoft.com/en-us/magazine/cc164128.aspx

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ No, at least not in my version (.NET 4.0). This is the reason why I created this in the first place... \$\endgroup\$ – Johan Sep 8 '14 at 22:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.