首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mono: IHttpAsyncHandler不给EndProcessRequest打电话

Mono: IHttpAsyncHandler不给EndProcessRequest打电话
EN

Stack Overflow用户
提问于 2014-07-18 11:44:02
回答 1查看 394关注 0票数 1

我使用ASP.NET IHttpAsyncHandler异步地将长轮询HTTP重定向到其他URL。它与.NET 4.5 (Windows7,8)完美地工作。但是不适用于Mono (Mono编译器版本3.2.8 (Debian 3.2.8+dfsg-4ubuntu1),Ubuntu14.04)。完成request.BeginGetResponse后,AsyncCallback不调用EndProcessRequest。

代码语言:javascript
复制
    public bool IsReusable { get { return true; } }

    public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
    {
        var request = (HttpWebRequest)HttpWebRequest.Create("http://www.google.com/");
        request.Method = context.Request.HttpMethod;

         request.UserAgent = context.Request.UserAgent;
        request.Accept = string.Join(",", context.Request.AcceptTypes);

        if (!string.IsNullOrEmpty(context.Request.Headers["Accept-Encoding"]))
        {
            request.Headers["Accept-Encoding"] = context.Request.Headers["Accept-Encoding"];
        }
        request.ContentType = context.Request.ContentType;
        request.ContentLength = context.Request.ContentLength;
        using (var stream = request.GetRequestStream())
        {
            CopyStream(context.Request.InputStream, stream);
        }
        return request.BeginGetResponse(cb, new object[] { context, request });
    }

    public void EndProcessRequest(IAsyncResult result)
    {

       // EndProcessRequest never called

        var context = (HttpContext)((object[])result.AsyncState)[0];
        var request = (HttpWebRequest)((object[])result.AsyncState)[1];
        using (var response = request.EndGetResponse(result))
        {
            context.Response.ContentType = response.ContentType;

            foreach (string h in response.Headers)
            {
                context.Response.AppendHeader(h, response.Headers[h]);
            }
            using (var stream = response.GetResponseStream())
            {
                CopyStream(stream, context.Response.OutputStream);
            }

            response.Close();
            context.Response.Flush();
        }
    }

    private void CopyStream(Stream from, Stream to)
    {
        var buffer = new byte[1024];
        while (true)
        {
            var read = from.Read(buffer, 0, buffer.Length);
            if (read == 0) break;

            to.Write(buffer, 0, read);
        }
    }

我不知道这种奇怪行为的原因。我认为这种行为是Mono框架中HttpWebRequest类的错误,但我不确定。这个问题可能有什么解决办法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-21 07:53:15

我们通过使用ThreadPool.QueueUserWorkItem找到了一些解决问题的方法:

代码语言:javascript
复制
    public bool IsReusable { get { return true; }}

    public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
    {
        return new AsynchOperation(cb, context, extraData).Start();
    }

    public void EndProcessRequest(IAsyncResult result) { }

    public void ProcessRequest(HttpContext context) { }

    private class AsynchOperation : IAsyncResult
    {
        private AsyncCallback cb;
        private HttpContext context;
        public WaitHandle AsyncWaitHandle { get { return null; } }
        public object AsyncState { get; private set; }
        public bool IsCompleted { get; private set; }
        public bool CompletedSynchronously { get { return false; } }

        public AsynchOperation(AsyncCallback callback, HttpContext context, object state)
        {
            cb = callback;
            this.context = context;
            AsyncState = state;
            IsCompleted = false;
        }

        public IAsyncResult Start()
        {
            ThreadPool.QueueUserWorkItem(AsyncWork, null);
            return this;
        }

        private void AsyncWork(object _)
        {
            var request = (HttpWebRequest)WebRequest.Create(boshUri);
            request.Method = context.Request.HttpMethod;

            // copy headers & body
            request.UserAgent = context.Request.UserAgent;
            request.Accept = string.Join(",", context.Request.AcceptTypes);
            if (!string.IsNullOrEmpty(context.Request.Headers["Accept-Encoding"]))
            {
                request.Headers["Accept-Encoding"] = context.Request.Headers["Accept-Encoding"];
            }
            request.ContentType = context.Request.ContentType;
            request.ContentLength = context.Request.ContentLength;

            using (var stream = request.GetRequestStream())
            {
                CopyStream(context.Request.InputStream, stream);
            }

            request.BeginGetResponse(EndGetResponse, Tuple.Create(context, request));
        }

        private void EndGetResponse(IAsyncResult ar)
        {
            var data = (Tuple<HttpContext, HttpWebRequest>)ar.AsyncState;
            var context = data.Item1;
            var request = data.Item2;

            try
            {
                using (var response = request.EndGetResponse(ar))
                {
                    context.Response.ContentType = response.ContentType;

                    // copy headers & body
                    foreach (string h in response.Headers)
                    {
                        context.Response.AppendHeader(h, response.Headers[h]);
                    }
                    using (var stream = response.GetResponseStream())
                    {
                        CopyStream(stream, context.Response.OutputStream);
                    }
                    context.Response.Flush();
                }
            }
            catch (Exception err)
            {
                if (err is IOException || err.InnerException is IOException)
                {
                    // ignore
                }
                else
                {
                    LogManager.GetLogger("ASC.Web.BOSH").Error(err);
                }
            }
            finally
            {
                IsCompleted = true;
                cb(this);
            }
        }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24824231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档