简体   繁体   English

HttpListener异步上下文泄漏

[英]HttpListener Async Context leaking

I have a simple HTTPServer implementation, that use the System.Net.HttpListener. 我有一个简单的HTTPServer实现,它使用System.Net.HttpListener。 It seems that my AsyncCallbacks isn't diposed somehow, and therefore is leading to a leak. 看来我的AsyncCallbacks没有以某种方式被释放,因此导致泄漏。

public abstract class HttpServer : IHttpServer, IDisposable
{
    protected readonly HttpListener HttpListener = new HttpListener();

    protected HttpServer(IEnumerable<string> prefixes)
    {
        WaitOnStartup = new AutoResetEvent(false);
        foreach (var prefix in prefixes)
        {
            HttpListener.Prefixes.Add(prefix);
        }
    }

    private void Process()
    {
        var result = HttpListener.BeginGetContext(ContextReceived, HttpListener);
        result.AsyncWaitHandle.WaitOne(30000);
        result.AsyncWaitHandle.Dispose();
    }

    protected abstract void ContextReceived(IAsyncResult ar);

    [...]
}

public class MyHttpServer : HttpServer
{
    public MyHttpServer(IEnumerable<string> prefixes) : base(prefixes) { }

    protected override void ContextReceived(IAsyncResult ar)
    {
        var listener = ar.AsyncState as HttpListener;
        if (listener == null) return;
        var context = listener.EndGetContext(ar);
        try
        {
            var request = context.Request;
            var response = context.Response;

            //handle the request...
        }
        finally
        {
            context.Response.Close();
            listener.Close();
        }
    }
}

If I run a memory profiler it looks like the async handle (BeginGetContext) isn't disposed, which means that AsyncCallback objects keep increasing.... 如果我运行内存探查器,则好像没有处理异步句柄(BeginGetContext),这意味着AsyncCallback对象不断增加。

What did I miss?? 我错过了什么??

UPDATE 11:45: 更新11:45:

Here is the Dipose() of the base class (HttpServer) 这是基类(HttpServer)的Dipose()

protected virtual void Dispose(bool disposing)
{
    if (_disposed)
        return;

    if (disposing)
    {
        // Free any other managed objects here. 
        HttpListener.Stop();
        HttpListener.Close();
        WaitOnStartup.Dispose();
    }

    // Free any unmanaged objects here. 
    //
    _disposed = true;
}

It looks like I managed to find the issue, I'm not excatly sure why yet tho... 看来我设法找到了问题,但我不确定为什么会这样。

But with inspiration from answer posted by @csharptest.net in Multi-threading with .Net HttpListener , I replaced the use of: 但是从@ csharptest.net在.Net HttpListener的多线程中发布的答案中得到启发,我替换了以下内容:

private void Process()
{
    var result = HttpListener.BeginGetContext(ContextReceived, HttpListener);
    result.AsyncWaitHandle.WaitOne(30000);
    result.AsyncWaitHandle.Dispose();
}

with

private void Process()
{
    while (HttpListener.IsListening)
    {
        var result = HttpListener.BeginGetContext(ContextReceived,     HttpListener);
        if (WaitHandle.WaitAny(new[] { result.AsyncWaitHandle, _shutdown })     == 0)
            return;
    }
}

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

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