记一次.NET HttpHandler接口性能优化过程(续)

第1章 简介

在上一篇文章中《记一次.NET HttpHandler接口性能优化过程》解决了同一客户端并发请求问题之后,IHttpHandler接口仍然是同步的模式,我们需要改成异步的模式,并将登录接口和业务接口拆开来,分别实现IRequiresSessionState和IReadOnlySessionState,已提高效率。这里需要思考两个问题:第一个问题是兼容:接口的修改需要考虑兼容性问题,原有接口建议不做改动;第二个问题是要考虑如何在前端代码不做任何改动的前提下,进行接口方法的重构。目的是做到接口的完美升级。

第2章 具体步骤

2.1 建立工厂类

建立一个Handler工厂类,实现IHttpHandlerFactory接口,在GetHandler方法内区分登录接口和业务接口,将这个EatsunMobileServiceHandler工厂类作为新接口的入口。

public class EatsunMobileServiceHandler : IHttpHandlerFactory
{
    public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
    {
        //......
        // 区分登录接口和业务接口Handler
        if (action == "LOGIN")
        {
            //登录
            return new EatsunMobileNewLoginHandler(param);
        }

        return new EatsunMobileNewHandler(param);
    }

    public void ReleaseHandler(IHttpHandler handler)
    {

    }
}

2.2 实现登录Handler

新建一个EatsunMobileNewLoginHandler类,实现IHttpHandler和 IRequiresSessionState,实现IRequiresSessionState的原因是现有登录逻辑本身需要读写Session ;而对于同一个客户端,登录业务本身不会有多个请求并发访问的情况。

public class EatsunMobileNewLoginHandler : IHttpHandler, IRequiresSessionState
{
    public bool IsReusable
    {
        get { return false; }
    }

    public EatsunMobileNewLoginHandler(JSONObject param)
    {
        _param = param;
    }

    public void ProcessRequest(HttpContext context)
    {
        //登录方法,读写Session
        Request(context);
    }
}

2.3 实现业务Handler

继承新建的异步基类:HttpAsyncHandler

public class EatsunMobileNewHandler : HttpAsyncHandler
{
    private JSONObject _param { get; set; }

    public EatsunMobileNewHandler(JSONObject param)
    {
        _param = param;
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

    public override void BeginProcess(HttpContext context)
    {
        //具体业务逻辑
        Request(context);
        EndProcess();
    }
    
}

HttpAsyncHandler基类实现IHttpAsyncHandler、IAsyncResult异步接口和IReadOnlySessionState只读session接口,业务逻辑只需要读取session,所以这个只需要基层IReadOnlySessionState,已获得同一客户端并发请求情况下更好的性能表现。

public abstract class HttpAsyncHandler : IHttpAsyncHandler, IAsyncResult, IReadOnlySessionState
{
    private bool _completed;
    private Object _state;
    private AsyncCallback _callback;
    private HttpContext _context;

    public object AsyncState
    {
        get { return _state; }
    }

    public WaitHandle AsyncWaitHandle
    {
        get { throw new NotImplementedException(); }
    }

    public bool CompletedSynchronously
    {
        get { return false; }
    }

    public bool IsCompleted
    {
        get { return _completed; }
    }

    public bool IsReusable
    {
        get { return false; }
    }

    public abstract void BeginProcess(HttpContext context);

    public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
    {
        _callback = cb;
        _context = context;
        _completed = false;
        _state = this;
       
        ThreadPool.QueueUserWorkItem(new WaitCallback(DoProcess), this);
        return this;
    }

    public void EndProcessRequest(IAsyncResult result)
    {

    }

    public void EndProcess()
    {
        if (!_completed)
        {
            try
            {
                _completed = true;
                if (_callback != null)
                    _callback(this);
            }
            catch (Exception) { }
        }
    }

    private static void DoProcess(object state)
    {
        HttpAsyncHandler handler = (HttpAsyncHandler)state;
        handler.BeginProcess(handler._context);
    }

    public void ProcessRequest(HttpContext context)
    {
        //row new NotImplementedException();
    }
}

第3章 总结

本章内容对原有IHttpHandler接口实现方法的重构,采用IHttpAsyncHandler异步的方式重新实现;并拆分出不需要写session的业务接口方法,实现IReadOnlySessionState接口,已达到同一客户端并发请求更好的性能表现。
 

猜你喜欢

转载自blog.csdn.net/dzh284616172/article/details/108370085