我有一个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应用程序调用的,如果这有任何区别。
答案 0 :(得分:3)
IsReusable不是保证。
只需重构您的处理程序并将所有交叉请求状态放入另一个类中。在最佳实践中明确区分Web应用程序中的交叉请求状态,因为它很危险。
答案 1 :(得分:1)
如果它是线程安全的,那么无论如何你都可以更好地重用。
IsReusable
返回true时:
ProcessRequest
。这意味着它可以减少重复的设置成本,但不一定(不保证)而不是完全 - 如果有多个并发调用同一个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!)