2014-10-27 3 views
0

У меня есть HttpListener, который я хочу не закрывать после каждого запроса, поэтому я использую BeginGetContext для получения запросов асинхронно. Это просто не работает должным образом.HttpListener BeginGetContext внезапно останавливается?

Главное начало правильно, поиск и назначение моего IP-адреса для функции StartListening(). Однако, когда я добираюсь до listener.BeginGetContext(new AsyncCallback(OnRequest), listener); в StartListening(), он переходит в Response.StartListening(ips); в Main, а затем просто останавливается. Я не знаю, почему. Любые намеки?

Вот что у меня есть.

Это где я начинаю слушать запросы:

public static void StartListening(string[] prefixes) 
    { 
     HttpListener listener = new HttpListener(); 

     if (prefixes == null || prefixes.Length == 0) 
      throw new ArgumentException("prefixes"); 

     foreach (string s in prefixes) 
     { 
      listener.Prefixes.Add("http://" + s + "/"); 
     } 
     listener.Start(); 
     Console.WriteLine("\nListening..."); 

     listener.BeginGetContext(new AsyncCallback(OnRequest), listener); 
    } 

А вот где я обрабатывать запросы:

public static void OnRequest(IAsyncResult result) 
    { 
     HttpListener listener = (HttpListener) result.AsyncState; 
     HttpListenerContext context = listener.EndGetContext(result); 


     string url = context.Request.RawUrl; 

     string[] split = url.Split('/'); 

     int lastIndex = split.Length - 1; 

     int x, y, z; 

     x = Convert.ToInt32(split[lastIndex]); 
     y = Convert.ToInt32(split[lastIndex - 1]); 
     z = Convert.ToInt32(split[lastIndex - 2]); 

     HttpListenerResponse response = context.Response; 

     Regex imageRegex = new Regex(@"SomethingSomething"); 
     var matches = imageRegex.Match(url); 

     if (matches.Success) 
     { 
      string path = @"C:\SomeDir"; 

      path = String.Format(path, matches.Groups[1].Captures[0], 
             matches.Groups[2].Captures[0], 
             matches.Groups[3].Captures[0]); 

      // Load the image 
      Bitmap bm = new Bitmap(path); 
      MemoryStream bmStream = new MemoryStream(); 
      bm.Save(bmStream, ImageFormat.Png); 
      byte[] buffer = bmStream.ToArray(); 

      // Get a response stream and write the response to it. 
      response.ContentLength64 = bmStream.Length; 
      response.ContentType = "image/png"; 
      response.KeepAlive = true; 
      Stream output = response.OutputStream; 
      output.Write(buffer, 0, buffer.Length); 

      // You must close the output stream. 
      output.Close(); 
      listener.Stop(); 
     } 

     response.Close(); 
     listener.BeginGetContext(new AsyncCallback(OnRequest), listener); 
    } 

И вот моя главная:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string name = (args.Length < 1) ? Dns.GetHostName() : args[0]; 
     try 
     { //Find the IPv4 address 
      IPAddress[] addrs = Array.FindAll(Dns.GetHostEntry(string.Empty).AddressList, 
       a => a.AddressFamily == AddressFamily.InterNetwork); 
      Console.WriteLine("Your IP address is: "); 
      foreach (IPAddress addr in addrs) 
       Console.WriteLine("{0} {1}", name, addr); 

      //Automatically set the IP address 
      string[] ips = addrs.Select(ip => ip.ToString()).ToArray(); 
      Response.StartListening(ips); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.Message); 
     } 
    } 
} 
+0

Это консольное приложение? Nevermind, вы используете Console.WriteLine, так что я предполагаю, что это так. – ProgramFOX

+0

Это проблема? – Khaine775

+0

Нет, но это объясняет, почему он останавливается. Я пишу ответ прямо сейчас. – ProgramFOX

ответ

0

После BeginGetContext, он извлекает запросы асинхронно, поэтому он не блокирует вызывающий поток (основной поток , в этом случае). И поскольку он не блокирует его, главный поток заканчивается, и поэтому ваша программа также заканчивается, потому что это основной поток.

Вы можете исправить это, используя ManualResetEvent (в пространстве имен System.Threading). Это блокирует основной поток.

class Program 
{ 
    public static ManualResetEvent ServerManualResetEvent; 
    static void Main(string[] args) 
    { 
     try 
     { 
      // your code to start the server 

      ServerManualResetEvent = new ManualResetEvent(false); 
      ServerManualResetEvent.WaitOne(); 
     } 
     catch 
     { 
      // your catch code 
     } 
    } 
} 

Сейчас основной поток блокируется, и ваша программа останавливается только если закрыть его, или, если вы остановите его из кода:

Program.ServerManualResetEvent.Set(); 

Тогда не блокирует основной поток больше.

+0

Когда я добираюсь до ServerManualResetEvent.WaitOne(); Я получаю исключение {«Объект ссылка не установлен на экземпляр объекта.»} После размещения именно там, где вы рекомендовали. – Khaine775

+0

@ Khaine775 Моя ошибка, я отредактировал мой ответ. – ProgramFOX

+0

Спасибо, это имеет смысл. Похоже, что теперь это работает. – Khaine775

Смежные вопросы