请记住,我不是多线程方面的专家,因此您应该尽可能小心地验证我所说的任何内容。
如果还有其他人knows,并且想窃取我的整个答案并编辑或更正细节,请随意这样做。
我们来一一解答您的疑问:
我到处添加了一些锁来防止竞争条件,但我很困惑:这些真的需要吗?我在文档中读到所有公共非静态方法都不是线程安全的。为什么我没有看到考虑这个事实的代码?
嗯,是的,也不是。锁通常用于防止多个线程同时访问同一数据结构,因为这会破坏数据结构。考虑在一个线程上对数组进行排序,然后在另一个线程的中间插入一个元素,正确计时这两个线程会破坏数组的内容。
现在,在您的代码中您正在锁定this
这绝不是一个好主意。外部代码might还对同一个对象进行锁定,这是您无法控制的,因此为了创建生产准备就绪代码,我不会那样做。
如果您的代码中需要锁,我将构造特定的锁对象并使用它们。
换句话说,添加以下内容:
private readonly object _Lock = new object();
然后你所到之处lock(this)
替换为lock(_Lock)
反而。这样,如果需要的话,您还可以拥有多个锁。
至于实际上是否需要锁,我并不是 100% 确定。我不确定的是,您在调用 Stop 之前锁定,并且您在回调中锁定,并在锁内检查侦听器是否仍在运行。
这将阻止您在接受请求之后但在实际处理请求之前停止侦听器。换句话说,听起来您会阻止在仍在处理打开的请求的情况下关闭服务器。
但是,不,您不会阻止这种情况,因为您可能会在回调中留下锁定部分后停止服务器,但在注释代码完全执行期间或之前,所以您仍然会遇到这个问题。
However它还意味着您已经有效地序列化了一些回调方法,即调用 EndGetContext 并重新启动 BeginGetContext 循环的部分。这是否是一个好的模式,我不知道。
HttpListenerContext 的行为如何?他与 HttpListener 有某种连接吗?或者我可以同时使用多个 HttpListenerContexts 吗?
这里我就做一个猜测。该类没有返回侦听器类的引用,or,它有一种线程安全的方式与之合作。
如果对请求/响应数据的每次访问都必须序列化,那么基于线程的 http 侦听器系统就不那么重要了。
无论如何,如果有疑问,请检查您正在访问的上下文类的方法和/或属性的文档,如果您需要采取措施确保线程安全,文档会这么说。
我听说 HttpListener 还没有为生产系统做好准备,但我从未见过支持这一说法的论据。到底是真是假?
(参见问题评论)
还有其他我没有提到的事情我应该考虑吗?
多线程代码是hard来写。从你的问题来看,我斗胆猜测你做的还不够多,说实话,虽然我做了很多,但我还是感觉如履薄冰。
我的建议如下:
- Do you really需要多线程吗?
- 您是否有其他对此有更多了解的同事可以为您提供帮助?