IHttpHandler.IsReusable有什么用途?

107

我正在编写一个 IHttpHandler,需要实现一个 IsReusable 属性。当我查看 MSDN 文档 时,它说:

获取指示另一个请求是否可以使用 IHttpHandler 实例的值。

这并不是很有帮助。 在哪些情况下应该使用可重用的处理程序,在哪些情况下它不应该是可重用的?

后续问题:

  1. 什么是可重用?
  2. Reusable = true时我能维护状态(即类变量)吗?
注:
1. IsReusable是IHttpHandler接口中的一个属性,用于指示 ASP.NET 是否可以将对象池化以供下一个请求使用。
2. 可重用的处理程序处理多个请求,并且由于 ASP.NET 使用线程池来处理请求,因此可以更快地响应请求。如果处理程序具有只读操作或不依赖于内部状态,则可以标记为可重用。如果处理程序维护状态或执行对资源的写操作,则不能共享处理程序实例。

9
请查看这里:http://foreachbiscuit.wordpress.com/2007/11/01/isreusable-on-the-ihttphandler-interface/。 - Homam
1
@IrishChieftain,目前我正在使用它来简单地流传一些日志信息。但是我正在尝试学习什么是IHttpHandlers以及何时和如何使用它们的影响。它们是许多人忘记的功能。 - Kees C. Bakker
如果您只是作为流一次读取一个日志,请将其设置为false...这个主题确实需要更仔细地研究。对于我来说,我开发的所有显示产品列表的网站都使用此处理程序。请关注相关问题中Branislav的答案 :) - IrishChieftain
我目前的理解是,当IReusable返回true时,类不应该包含任何状态。它应该只是一个处理程序(几乎像静态处理程序)。 - Kees C. Bakker
显示剩余4条评论
3个回答

96

该属性指示是否可以使用同一IHttpHandler实例处理多个请求。默认情况下,在请求管道结束时,所有放置在HttpApplication的handlerRecycleList中的http处理程序都将设置为null。如果一个处理程序是可重用的,它将不会被设置为null,并且该实例将在下一个请求中被重复使用。

主要优点是性能提升,因为需要垃圾回收的对象将减少。
可重用处理程序最重要的痛点是它必须是线程安全的。这并不是微不足道的,需要付出一些努力。

我个人建议,如果你仅使用托管资源,则保留默认值(不可重用),因为垃圾收集器应该很容易处理它们。与引入难以找到的线程错误的风险相比,可重用处理程序带来的性能提升通常是微不足道的。

如果决定重复使用处理程序,您应该避免在类变量中维护状态,因为如果处理程序实例被同时访问,则多个请求将写入/读取这些值。


1
你上次关于避免在类变量中维护状态的建议有点令人困惑。假设你将IsReusable设置为false,那么是否就不可能有另一个请求(并发或非并发)访问同一实例的HttpHandler,因此在类变量中维护状态是安全的? - Ben Amada
2
当然。我已经重新表述了最后的建议,强调它仅适用于IHttpHandler被重复使用的情况。感谢澄清,Ben! - Branislav Abadjimarinov
8
就我所知,我已经实现了很多 IHttpHandler 并将 IsReusable 设置为 true,并且没有出现任何问题。要记住的主要是不要在类中编写任何变量,而应该在函数中使用局部变量。 - dana
7
很好的解释,清晰明了。我希望MSDN文章也能这么简明扼要。 - AlexVPerl
1
@Branislav - 如果我理解你的回答是正确的,那么不仅不同的线程可以同时利用不同的处理程序实例,而且不同的线程也可以同时执行相同的处理程序实例。 - Ian
显示剩余4条评论

11

显然,这会使处理程序保持在内存中并能够处理多个请求。如果设置为false,则必须为每个传入的请求创建处理程序的新实例。

以下是一个问题,展示了当不正确使用时会发生什么:

使用HttpHandler流式传输数据库图像


你有一些文件支持你的回答吗? - Kees C. Bakker
4
像您一样,我在MSDN上也找不到令人满意的文档,因此必须测试从数据库加载图像并显示在电子商务网站页面上的过程,然后观察发生了什么 :) - IrishChieftain

5
处理程序的回收利用比每次请求时新建处理程序更加经济实惠,服务器将使用更少的内存,减轻了垃圾回收的工作。如果处理程序处于可以处理新请求不会有问题的状态(即已重置处理程序实例中的任何状态),则应该被视为可重复使用的。
编辑:
我不确定我的答案是否正确地定义了重用。实际上,它允许并发重用,因此最好避免状态或以线程安全的方式进行仔细管理。

我也这么认为。你说得对,实际(基本)问题是:“什么是重用?” - Kees C. Bakker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接