【问题标题】:Why HttpListener Start method Dispose stuff on exception ?为什么 HttpListener Start 方法 Dispose 异常的东西?
【发布时间】:2012-06-25 06:24:55
【问题描述】:

HttpListener 有一些我真的不明白的地方。

下面的代码不言自明,并以一种方式暴露了“问题”。

我只是简单地实例化了两个不同的 HttpListener,每个都具有相同的单个前缀。 然后我启动第一个监听器,当然当我尝试启动第二个监听器(相同的前缀)时我得到一个 HttpListenerException .. 到目前为止一切顺利。

好吧,我的错(如果我们正在使用配置工具,则是最终用户的错)。不用惊慌,我将清除第二个侦听器的前缀并指定一个新的...或停止第一个侦听器并尝试重新启动第二个侦听器,或者其他...

但不能做到这一切,因为一旦我尝试访问第二个侦听器前缀或其他任何内容,我就会得到一个 ObjectDisposedException(无法访问已处置的对象。对象名称:'System.Net.HttpListener') .

我的问题是为什么? 我在 HttpListener 文档中看不到任何内容,说明在 HttpListenerException 上,一些 HttpListener 对象的内部内容以某种方式被处理,并且该对象从那时起就没有用了......

所以这意味着如果我启动一个 HttpListener 并得到一个 HttpListenerException ,无论如何我都必须重新创建一个全新的 HttpListener 对象?对我来说似乎有点奇怪(但可能有另一种方式或一个很好的理由)。

提前感谢您的回答!!

var listener1 = new HttpListener();
listener1.Prefixes.Add("http://localhost:8080/MyHandler/");
listener1.Start();

var listener2 = new HttpListener();
listener2.Prefixes.Add("http://localhost:8080/MyHandler/");

try
{
   listener2.Start();
}
catch (HttpListenerException ex)
{
  listener2.Prefixes.Clear(); // BAM ! ObjectDisposedException
}

【问题讨论】:

  • @dlev:伙计,我必须整天跟着你,告诉你把你的 cmets 作为答案吗?您是如何获得 18K 代表的? :)
  • @MusiGenesis 很好。我将再次听取您的建议 :) 这些天我的第一直觉是将这样的一次性想法发布为 cmets,因为我通常更喜欢充实实际答案(除非实际答案实际上是单行的。)说,我可能朝那个方向走得太远了。好东西你在附近!

标签: c# .net httplistener


【解决方案1】:

异常意味着发生了可怕的错误。它不会允许毫无戒心的消费者继续使用可能损坏且不稳定的对象,而是自行处置。只需创建新的侦听器,您就不必担心使用可能无用的对象。

【讨论】:

  • 我有点同意。但说真的......我知道 HttpListener 无法启动,因为其中一个前缀已经在使用中,但对我来说,在这个特定的上下文中处理它是不合理的(这不是一个非常错误的问题)。实际上 HttpListener 甚至没有启动,所以它只是一个初始化的原始对象,什么都不做!所以也许问题更多地在于这个 HttpListener 的设计(我只是反编译它并自己检查代码,看看是否有很好的理由在这种情况下处理它......也许我错过了一些东西)。
  • @user1188511 如果您查看代码,您会发现如果在Start() 期间出现anything 出错,那么它会将自身置于关闭状态,然后拒绝做任何进一步的事情。您会注意到它捕获Exception,而不是更具体的异常,因此不允许进一步使用是所采用的路径。从理论上讲,它可以改进为首先捕获已知的、可恢复的异常,尽管我怀疑这是 BCL 团队的高优先级。
  • 是的,只是注意到了同样的情况。对象并不是真正的 Disposed 而是 Closed,因此返回 HttpListenerClosedException 会更有意义(Dispose 会导致混乱,没有任何东西真正 Disposed)。特别是考虑到 HttpListener 上有一个 Close 方法记录为“调用此方法后,您不能再使用 HttpListener 对象”这一事实。因此,该异常绝对应该更好地命名为连贯性(并且 HttpListener 不会在任何异常上关闭,即使是非常容易恢复的情况)。无论如何,感谢您的回答,而不是我必须承认的答案;)
猜你喜欢
  • 1970-01-01
  • 2019-02-20
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-12
  • 1970-01-01
相关资源
最近更新 更多