欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-28 16:52:21
...

第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接口,已达到同一客户端并发请求更好的性能表现。