title: Thread-safe server
body: <p>I try to implement multithreaded server. Few clients (&lt; 10) will send some data to the server (<code>PUT</code> request). On the <code>GET</code> server has to send collection with this data. Here is my server code:</p>
  
  <pre><code>class Server
  {
      private HttpListener httpListener;
      private static System.Threading.AutoResetEvent listenForNextRequest = new System.Threading.AutoResetEvent(false);
      public static BlockingCollection&lt;NodeInfo&gt; locations = new BlockingCollection&lt;NodeInfo&gt;();
  
      public Server()
      {
          const string ip = "127.0.0.1";
          const int port = 9999;
          string prefix = String.Format("http://{0}:{1}/", ip, port.ToString());
  
          httpListener = new HttpListener();
          httpListener.Prefixes.Clear();
          httpListener.Prefixes.Add(prefix);
  
          Console.WriteLine("HTTP server is running ...");
          Console.WriteLine("Listening on {0} ...\n", prefix);
      }
  
      public void Start()
      {
          httpListener.Start();
          ThreadPool.SetMaxThreads(10, 10);
          ThreadPool.QueueUserWorkItem(new WaitCallback(Listen));
          Thread.Sleep(7000);
      }
  
      internal void Stop()
      {
          httpListener.Stop();
      }
  
      private void Listen(object state)
      {
          while (httpListener.IsListening)
          {
              httpListener.BeginGetContext(new AsyncCallback(ListenerCallback), httpListener);
              listenForNextRequest.WaitOne();
          }
      }
  
      private static void ListenerCallback(IAsyncResult result)
      {
          HttpListener listener = (HttpListener)result.AsyncState;
  
          // Request
          HttpListenerContext context = listener.EndGetContext(result);
  
          if (context.Request.HttpMethod.Equals("PUT"))
          {
              PutRequestProcess(context);
          }
  
          if (context.Request.HttpMethod.Equals("GET"))
          {
              GetRequestProcess(context);
          }
  
          // Process next request
          result = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);
      }
  
      private static void PutRequestProcess(HttpListenerContext context)
      {
          // Request object
          HttpListenerRequest request = context.Request;
  
          using (Stream stream = request.InputStream)
          {
              // Deserialize
              DataContractSerializer ser = new DataContractSerializer(typeof(NodeInfo));
              XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas());
  
              // Deserialize the data and read it from the instance.
              NodeInfo nodeInfo = (NodeInfo)ser.ReadObject(reader, true);
              reader.Close();
              stream.Close();
  
              locations.Add(nodeInfo);
          }
  
          // Response object
          HttpListenerResponse response = context.Response;
  
          response.StatusCode = (int)HttpStatusCode.OK;
  
          using (Stream stream = response.OutputStream)
          {
              stream.Close();
          }
      }
  
      private static void GetRequestProcess(HttpListenerContext context)
      {
          // Response object
          HttpListenerResponse response = context.Response;
  
          response.StatusCode = (int)HttpStatusCode.OK;
  
          using (Stream stream = response.OutputStream)
          using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream))
          {
              DataContractSerializer ser = new DataContractSerializer(typeof(List&lt;NodeInfo&gt;));
              {
                  writer.WriteStartDocument();
                  ser.WriteObject(writer, locations.ToList());
              }
  
              stream.Close();
          }
      }
  }
  </code></pre>
  
  <p><code>PUT</code> request seems to be working. But when I try to receive this collection (<code>GET</code> request) I have an exception at deserialization: <code>Unexpected end of file...</code> In debugger there are not all tags in the end of <code>XML</code> string. I think writing thread (server) doesn't finish. How can I fix it?
  Also I have few questions. Is this implementation thread-safe? If I use concurrent collections I don't need to use semaphore or other synchronization?</p>
  
  <p>Thank you very much!</p>