private async void ProcessRequest(HttpListenerContext context, AppFunc app, OwinLogger logger)
        {
            OwinHttpListenerContext owinContext = null;

            try
            {
                GetPathAndQuery(context.Request, out var pathBase, out var path, out var query);
                owinContext = new OwinHttpListenerContext(context, pathBase, path, query);
                await app.Invoke(owinContext.Environment);

                if (!context.Connection.IsClosed)
                {
                    owinContext.Response.CompleteResponse();
                }

                owinContext.Response.Close();

                owinContext.End();
                owinContext.Dispose();
            }
            catch (Exception ex)
            {
                if (owinContext != null)
                {
                    owinContext.End(ex);
                    owinContext.Dispose();
                }
            }
        }
        private void StartProcessingRequest(HttpListenerContext context)
        {
            Interlocked.Decrement(ref _currentOutstandingAccepts);
            Interlocked.Increment(ref _currentOutstandingRequests);
            OffloadStartNextRequest();
            OwinHttpListenerContext owinContext = null;

            try
            {
                string pathBase, path, query;
                GetPathAndQuery(context.Request, out pathBase, out path, out query);
                owinContext = new OwinHttpListenerContext(context, pathBase, path, query, _disconnectHandler);
                PopulateServerKeys(owinContext.Environment);
                Contract.Assert(!owinContext.Environment.IsExtraDictionaryCreated,
                                "All keys set by the server should have reserved slots.");

                _appFunc(owinContext.Environment)
                .Then((Func <Task>)owinContext.Response.CompleteResponseAsync, runSynchronously: true)
                .Then(() =>
                {
                    owinContext.Response.Close();
                    EndRequest(owinContext, null);
                }, runSynchronously: true)
                .Catch(errorInfo =>
                {
                    EndRequest(owinContext, errorInfo.Exception);
                    return(errorInfo.Handled());
                });
            }
            catch (Exception ex)
            {
                EndRequest(owinContext, ex);
            }
        }
        private void EndRequest(OwinHttpListenerContext owinContext, Exception ex)
        {
            Interlocked.Decrement(ref _currentOutstandingRequests);

            if (ex != null)
            {
                LogHelper.LogException(_logger, "Exception during request processing.", ex);
            }

            if (owinContext != null)
            {
                owinContext.End(ex);
                owinContext.Dispose();
            }

            // Make sure we start the next request on a new thread, need to prevent stack overflows.
            OffloadStartNextRequest();
        }
        // This needs to be separate from ProcessRequestsAsync so that async/await will clean up the execution context.
        // This prevents changes to Thread.CurrentPrincipal from leaking across requests.
        private async Task ProcessRequestAsync(HttpListenerContext context)
        {
            OwinHttpListenerContext owinContext = null;

            try
            {
                string pathBase, path, query;
                GetPathAndQuery(context.Request, out pathBase, out path, out query);
                owinContext = new OwinHttpListenerContext(context, pathBase, path, query, _disconnectHandler);
                PopulateServerKeys(owinContext.Environment);
                Contract.Assert(!owinContext.Environment.IsExtraDictionaryCreated,
                                "All keys set by the server should have reserved slots.");

                await _appFunc(owinContext.Environment);

                await owinContext.Response.CompleteResponseAsync();

                owinContext.Response.Close();

                owinContext.End();
                owinContext.Dispose();

                Interlocked.Decrement(ref _currentOutstandingRequests);
            }
            catch (Exception ex)
            {
                Interlocked.Decrement(ref _currentOutstandingRequests);
                LogHelper.LogException(_logger, "Exception during request processing.", ex);

                if (owinContext != null)
                {
                    owinContext.End(ex);
                    owinContext.Dispose();
                }
            }
        }