简体   繁体   English

Windows服务启动时HttpLisenter启动方法失败

[英]HttpLisenter Start method fails on windows service start

I've been fooling around with the HttpListenter stuff found at: 我一直在鬼混HttpListenter的资料,网址为:

http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx 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. 它可以在标准控制台应用程序上很好地工作,但是我正在尝试使其作为Windows服务工作。 Application Logs show that when the service starts up, it fails on the HttpListener.Start() method. 应用程序日志显示,服务启动时,它将在HttpListener.Start()方法上失败。 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. 您实际上得到的异常是StackOverflowException(唯一的try-catch块无法try-catch异常),无论您做什么,应用程序都会中断。

Remove your while loop (just call Listen once) and try using the following approach in your Listen method. 删除while循环(只需调用一次Listen),然后在Listen方法中尝试使用以下方法。

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 这将使用单个HttpListener创建您要查找的循环

Hope this helps 希望这可以帮助

UPDATE : 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. UPDATE :如果取消注释请求处理代码,您将注意到不会发生异常,因为在调用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. 通过只调用将间接返回的listener.Start()然后返回true,您就以非常快的速度循环创建了许多监听器。

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. 最好让一个侦听器异步处理所有请求,因为如果您的一个请求花费10秒执行循环,则在您响应发出请求的客户端之前,不会创建另一个侦听器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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