IHttpHandler IsReusable,但没有被重用

时间:2012-09-02 20:57:56

标签: c# asp.net silverlight

我有一个IHttpHandler,我相信它可以从重用中受益,因为它设置起来很昂贵,并且是线程安全的。但是正在为每个请求创建一个新的处理程序。我的处理程序没有被重用。

以下是我的简单测试用例,没有昂贵的设置。这个简单的案例证明了我的问题:

public class MyRequestHandler : IHttpHandler
{
    int nRequestsProcessed = 0;

    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        nRequestsProcessed += 1;
        Debug.WriteLine("Requests processed by this handler: " + nRequestsProcessed);
        context.Response.ContentType = "text/plain";
        context.Response.Write("Hello World");
    }
}

Requests processed by this handler: 1
Requests processed by this handler: 1
Requests processed by this handler: 1
Requests processed by this handler: 1... at least 100 times. I never see > 1.

我是否误解了IsReusable的工作原理?还有什么东西可以打败重复使用吗?我的处理程序是从Silverlight应用程序调用的,如果这有任何区别。

2 个答案:

答案 0 :(得分:3)

IsReusable不是保证。

只需重构您的处理程序并将所有交叉请求状态放入另一个类中。在最佳实践中明确区分Web应用程序中的交叉请求状态,因为它很危险。

答案 1 :(得分:1)

如果它是线程安全的,那么无论如何你都可以更好地重用。

IsReusable返回true时:

  1. 首先创建一个处理程序实例。
  2. 调用ProcessRequest
  3. 可能会放入池中再次使用。
  4. 这意味着它可以减少重复的设置成本,但不一定(不保证)而不是完全 - 如果有多个并发调用同一个URI,那么就需要创建几个这样的处理程序来处理他们在同一时间。

    这种方法的好处在于(当池化确实发生时),处理程序实际上不必是线程安全的。

    既然你的,我们可以通过两种方式之一做得更好。

    一,是将所有功能放入另一个类中。然后处理程序可以只是一个瘦的类,其中ProcessRequest传递给那个的静态实例。

    同样,我们可以使用IHttpHandlerFactory对您当前的类执行此操作:

    public class MyRequestHandlerFactory : IHttpHandlerFactory
    {
      private static MyRequestHandler SingletonHandler = new MyRequestHandler();
      IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
      {
        return SingletonHandler;
      }
      void ReleaseHandler(IHttpHandler handler)
      {
        //do nothing
      }
    }
    

    使用上面的类,您只需更改Web.Config即可引用当前引用MyRequestHandlerFactory的{​​{1}},它将完美运行。

    (除非你实际上并不像你想象的那样是线程安全的,在这种情况下 - oopsie!)