生产就绪,multithreading的c#http服务器

我在c#.NET中实现了一个HTTP服务器:

public class HttpServer { private HttpListener listener; public HttpServer() { listener = new HttpListener(); listener.Prefixes.Add("http://localhost:8080/"); } public void Start() { lock(this) { listener.Start(); AsyncProcessing(listener); } } public void Stop() { lock (this) { listener.Stop(); } } private void AsyncProcessing(HttpListener listener) { if (listener == null) return; listener.BeginGetContext(new AsyncCallback(Callback), listener); } private void Callback(IAsyncResult result) { HttpListenerContext context = null; lock(this) { HttpListener listener = (HttpListener)result.AsyncState; if (!listener.IsListening) return; context = listener.EndGetContext(result); AsyncProcessing(listener); } /* handle request */ } } 

我对此实现有一些疑问:

  • 我在这里和那里添加了一些锁以防止竞争条件,但我很困惑:那些真的需要吗? 我在文档中读到所有公共非静态方法都不是线程安全的。 为什么我没有看到考虑这个事实的代码?
  • HttpListenerContext如何表现? 他是否与HttpListener有某种联系? 或者我可以同时使用多个HttpListenerContexts吗?
  • 我听说HttpListener不会为生产系统做好准备,但我从未见过支持这种说法的论据。 这是真的吗?
  • 还有其他我应该考虑的事情,我没有提到过吗?

谢谢你的想法

请记住,我不是multithreading的专家,因此您应该尽可能地尽力validation我说的任何内容。

如果有其他人知道 ,并且只想窃取我的整个答案,只是编辑或更正细节,请随意这样做。

让我们一个一个地处理你的问题:

我在这里和那里添加了一些锁以防止竞争条件,但我很困惑:那些真的需要吗? 我在文档中读到所有公共非静态方法都不是线程安全的。 为什么我没有看到考虑这个事实的代码?

嗯,是的,不。 锁通常用于防止多个线程同时访问同一数据结构,因为它会破坏数据结构。 考虑在一个线程上对数组进行排序,在另一个线程中插入一个元素,这两个线程正确的时序会破坏数组的内容。

现在,在您的代码中,您将锁定this ,这绝不是一个好主意。 外部代码也可能锁定同一个对象,这是你无法控制的,所以为了创建生产就绪代码,我不会这样做。

如果您需要在代码中使用锁,我将构造特定的锁对象并使用它们。

换句话说,添加:

 private readonly object _Lock = new object(); 

然后你到处都lock(this)lock(_Lock)代替它。 这样,如果需要,您还可以拥有多个锁。

至于实际需要锁,我不是100%肯定。 我不确定的事情是你在调用Stop之前锁定,并且你在锁定回调并在锁内部检查监听器是否仍在运行。

这将阻止您在接受请求后但在实际处理请求之前停止侦听器。 换句话说,听起来你会阻止关闭服务器仍然处理打开的请求。

但是,不,你不会阻止它,因为你可能会在回调中离开锁定部分后停止服务器,但在评论代码完全执行期间或之前,所以你仍然会遇到这个问题。

但是,这也意味着您已经有效地序列化了一些回调方法,即调用EndGetContext并重新启动BeginGetContext循环的部分。 不知道这是不是一个好的模式,我不知道。

HttpListenerContext如何表现? 他是否与HttpListener有某种联系? 或者我可以同时使用多个HttpListenerContexts吗?

我在这里猜一猜。 该类没有引用回侦听器类, 或者它具有与之协作的线程安全方式。

如果必须序列化对请求/响应数据的每次访问,那么基于线程的http侦听器系统就不会太多了。

在任何情况下,如果有疑问,请检查您正在访问的上下文类的方法和/或属性的文档,如果您需要采取措施来确保线程安全,文档将会这样说。

我听说HttpListener不会为生产系统做好准备,但我从未见过支持这种说法的论据。 这是真的吗?

(见问题评论)

还有其他我应该考虑的事情,我没有提到过吗?

multithreading代码很难编写。 根据你的问题判断,我猜想你没有做过很多事情,说实话,尽管我已经做了很多,但我还是觉得我已经处于困境之中。

我的建议如下:

  • 真的需要multithreading吗?
  • 您是否有其他同事了解更多可以帮助您的事情?