简体   繁体   中英

HttpLisenter Start method fails on windows service start

I've been fooling around with the HttpListenter stuff found at:

http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx

It works great on a standard console app, but I'm trying to get it working as a windows service. Application Logs show that when the service starts up, it fails on the HttpListener.Start() method. I'm pretty stumped as to why this might happen.

Here's the class (proof of concept quality here :)

public class Server
{
    public Server()
    {
        var thread = new Thread((Start));
        thread.Start();
    }

    public static void Start()
    {
        while(Listen())
        {
        }
    }

    private static bool Listen()
    {
        var prefixes = new[] {"http://192.168.0.7/"};

        if (!HttpListener.IsSupported)
        {
            Console.WriteLine ("Windows XP SP2 or Server 2003 is required to use the HttpListener class.");
            return false;
        }
        // URI prefixes are required, 
        // for example "http://contoso.com:8080/index/".
        if (prefixes == null || prefixes.Length == 0)
          throw new ArgumentException("prefixes");

        // Create a listener.
        HttpListener listener = new HttpListener();

        // Add the prefixes. 
        foreach (string s in prefixes)
        {
            listener.Prefixes.Add(s);
        }

        listener.Start();   //THIS FAILS IN WINDOWS SERVICE AS LOCAL SYSTEM

        //Console.WriteLine("Listening...");
        //// Note: The GetContext method blocks while waiting for a request. 
        //HttpListenerContext context = listener.GetContext();
        //HttpListenerRequest request = context.Request;
        //// Obtain a response object.
        //HttpListenerResponse response = context.Response;
        //// Construct a response. 
        //string responseString = "<HTML><BODY> " + DateTime.Now + "</BODY></HTML>";
        //byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
        //// Get a response stream and write the response to it.
        //response.ContentLength64 = buffer.Length;
        //System.IO.Stream output = response.OutputStream;
        //output.Write(buffer,0,buffer.Length);
        //// You must close the output stream.
        //output.Close();
        //listener.Stop();

        return true;
    }

}

Relavent Logs: Error:

Application: Stout.Workers.Service.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Net.HttpListenerException
Stack:
   at System.Net.HttpListener.Start()
   at Stout.Workers.Service.Server.Listen()
   at Stout.Workers.Service.Server.Start()
   at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Threading.ThreadHelper.ThreadStart()

Error:

Faulting application name: Stout.Workers.Service.exe, version: 0.0.0.0, time stamp: 0x50d0cd99
Faulting module name: KERNELBASE.dll, version: 6.2.9200.16451, time stamp: 0x50988950
Exception code: 0xe0434352
Fault offset: 0x00014b32
Faulting process id: 0x1e70
Faulting application start time: 0x01cddd5bb3e8500b
Faulting application path:     C:\Users\Chad\Dropbox\Personal\Projects\Stout\Stout\Workers\Service\bin\Debug\Stout.Workers.Service.exe
Faulting module path: C:\Windows\SYSTEM32\KERNELBASE.dll
Report Id: f1aa9986-494e-11e2-be9b-685d43b0551c
Faulting package full name: 
Faulting package-relative application ID: 

Info:

Fault bucket , type 0
Event Name: CLR20r3
Response: Not available
Cab Id: 0

Problem signature:
P1: stout.workers.service.exe
P2: 0.0.0.0
P3: 50d0cd99
P4: System
P5: 4.0.30319.18016
P6: 505702c9
P7: 206c
P8: 5c
P9: System.Net.HttpListenerException
P10: 

I guess you are trying to accept multiple requests on your listener. If you read your code carefully you will find you are instantiating infinite number of listeners instead of creating a single listener to handle multiple calls.

The exception you are actually getting is a StackOverflowException (the only exception that cannot be catched with try-catch blocks) The application breaks no matter what you do.

Remove your while loop (just call Listen once) and try using the following approach in your Listen method.

HttpListener listener = new HttpListener();
//add your prefixes here
listener.Start();
AsyncCallback processRequest = delegate(IAsyncResult result)
{
    //set the listener to listen for next request
    listener.BeginGetContext(processRequest, listener);
    HttpListenerContext context = listener.EndGetContext(result);
    //Your code to handle the request here
}

listener.BeginGetContext(processRequest, listener);

This creates the loop you are looking for with a single HttpListener

Hope this helps

: If you uncomment the request handling code you will note that the exception does not occur since you block the thread when calling listener.GetContext() and the listener hangs until it receives a request and the Listen method does not return. :如果取消注释请求处理代码,您将注意到不会发生异常,因为在调用listener.GetContext()时阻塞了线程,并且侦听器将挂起,直到接收到请求并且Listen方法不会返回为止。 By just calling listener.Start() which returns inmediatelly and then returning true you are looping at a really fast rate creating many listeners.

Your code might work this way but it's inefficient because you have to create a listener for every request. It's better let a single listener handle all the requests asynchronously because if one of your request takes 10 seconds to execute your loop won't create another listener until you respond to the requesting client.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM