http请求入队列以及遇到的问题总结

                                                       http请求入队列排队执行以及遇到的问题总结

队列以及加锁的注意事项,如下所示,记录之,线程的知识体系尚需完善。

public class HttpContext
    {
        public HttpListenerContext httpListenerContext { get; set; }
        public Hashtable para { get; set; }
    }
 public partial class Form1 : Form
    {
        private HttpListener m_verifyhttplisten;
        private object m_listenlocker = new object();
        private ConcurrentQueue<HttpContext> m_httpconQueue = new ConcurrentQueue<HttpContext>();
        HttpContext m_httpContext = new HttpContext();
        HttpListenerContext httpListener;
        object locker = new object();
        static int num = 1;
        public Form1()
        {
            InitializeComponent();
            m_verifyhttplisten = new HttpListener();
            m_verifyhttplisten.Prefixes.Add("http://192.168.1.199:50000/verify/");
            m_verifyhttplisten.Start();
            ThreadPool.QueueUserWorkItem(new WaitCallback(obj =>
                {
                    httpRequestHandle2();
                }));
            Thread thread2 = new Thread(ceshi);
            thread2.Start();
        }
        private void httpRequestHandle2()
        {
            while (true)
            {
                try
                {
                    //等待请求连接,没有请求则GetContext处于阻塞状态
                    HttpListenerContext requestContext = m_verifyhttplisten.GetContext();
                    ThreadPool.QueueUserWorkItem(new WaitCallback(verifyhttplistern), requestContext);
                }
                catch (Exception ex)
                {
                    //LogHelperBLL.CreateErrorLogTxt("httpRequestHandle2", ex.Source, ex.Message);
                }
            }
        }
        private void verifyhttplistern(object requestcontext)
        {
            try
            {
                lock (m_listenlocker)
                {
                    //获取请求参数                    
                    Hashtable para = new Hashtable();
                    //返回值                     
                    Hashtable rtn = new Hashtable();
                    //客户端发送过来的信息
                    HttpListenerContext request = (HttpListenerContext)requestcontext;

                    //获取Post请求中的参数和值帮助类
                    HttpListenerHelper httppost = new HttpListenerHelper(request);

                    //获取Post过来的参数和数据  
                    List<HttpListenerPostValue> lst = httppost.GetHttpListenerPostValue();
                    try
                    {
                       
                                HttpContext httpContext = new HttpContext(); 
                                httpContext.httpListenerContext = request;
                                httpContext.para = para;
                                try
                                {
                                    m_httpconQueue.Enqueue(httpContext);
                                }
                                catch (Exception ex)
                                {
                                   
                                }
                        }
                               
                    }
                    catch (Exception ex)
                    {
                       
                    }
                }
            }
            catch (Exception ex)
            {
                
            }
        }
        private void ceshi()
        {
            while (true)
            {
                try
                {
                    Hashtable para = new Hashtable();
                    Hashtable rtn = new Hashtable();
                    lock (locker)
                    {
                        HttpContext httpContext = new HttpContext();
                        if (m_httpconQueue.Count > 0)
                        {

                            m_httpconQueue.TryDequeue(out httpContext);
                        }
                        else if (m_httpconQueue.Count == 0)
                        {
                            continue;
                        }
                        HttpListenerContext request = httpContext.httpListenerContext;
                        para = httpContext.para;
                        try
                        {
                            rtn.Add("status", 200);
                            rtn.Add("code", 1);
                            rtn.Add("message", "ceshi");
                            //Response  
                            request.Response.StatusCode = 200;
                            request.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                            request.Response.ContentType = "application/json";
                            request.Response.ContentEncoding = Encoding.UTF8;
                            byte[] buffer = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(rtn));
                            request.Response.ContentLength64 = buffer.Length;
                            var output = request.Response.OutputStream;
                            output.Write(buffer, 0, buffer.Length);
                            output.Close();
                        }
                        catch (System.Net.WebException ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    }
                    Thread.Sleep(100);
                }
                catch (Exception ex)
                {
                }
            }
        }

    }
    

 上面的程序段时不时的会报“提交响应后无法执行此操作 ”这个错误。我就一直被这个错误困扰误导了,一直沿着这个方向找问题。后来发现我找问题的方向是不对的。而是应该是线程安全方面的问题。队列入队的对象加锁出现问题,导致出队列执行响应的时候报这个异常。即:入队的时候的这个对象应该是局部变量,加在锁内。

如上图所示:入队的这个对象是全局的对象,就会导致异常。

猜你喜欢

转载自blog.csdn.net/ezreal_pan/article/details/85614128