5

我有一个 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 应用程序中调用。

4

2 回答 2

3

IsReusable 不是保证。

只需重构您的处理程序并将所有交叉请求状态放入不同的类。无论如何,在最佳实践中清楚地分离 Web 应用程序中的交叉请求状态,因为它很危险。

于 2012-09-02T21:03:25.700 回答
1

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

IsReusable返回 true 时:

  1. 首先创建处理程序的一个实例。
  2. ProcessRequest被称为。
  3. 可能会被放入池中以再次使用。

这意味着它可以减少重复的设置成本,但不一定(不能保证)并且不完全 - 如果对同一个 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它当前引用的位置MyRequestHandler,它就会完美地工作。

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

于 2012-09-03T00:08:09.257 回答