zoukankan      html  css  js  c++  java
  • ASP.NET服务器端多线程设计——异步IHttpHandler

    在.NET系统中,可以通过Thread直接创建线程。但为了避免使用过多的线程对系统性能做成影响,微软特别开发了一个ThreadPool(CLR线程池)对线程进行管理。

    ThreadPool.QueueUserWorkItem(new WaitCallback(method), objcet);//新建线程

    CLR线程池的线程却分成两种:工作者线程与IO线程
    ThreadPool.GetAvailableThreads(out int a1, out int a2);//a1为工作者线程,a2为IO线程

    一般ASP.NET的页面请求会在工作者线程中运行,但当使用硬盘文件读取,外部数据交换时就可以使用IO线程来降低工作者线程的压力。(注意:如果读取小型文件时异步使用IO线程,工作效率可能比单线程操作还要低,建议阁下参考Jeffrey Richter名著《CLR via C#》

    当客户端要获取网络文件时,一般会使用IHttpHandler方式,若是文件流量太大时,CLR线程池的工作者线程就被会长期占用并处于等待状态,当线程大于线程池的最大值 (IIS5.0默认值为25*CPU数,IIS 7.0默认值为250*CPU数)的时候,其他请求将处于等待状态,这样会对服务器造成压力。这时候可以通过异步的HttpHanlder利用IO线程对文件进行异步处理。其作用在于及时释放CLR线程池的工作者线程,将读取文件的工作交于异步IO线程。

    class File

    {

        FileStream fileStream;

        byte[] bytes;

    }

    public class Handler : IHttpAsyncHandler {     

          //异步HttpHandler继承于IHttpAsyncHandler,并包含BeginProcessRequest方法和EndProcessRequest方法
          public byte[] bytes;
          public HttpContext context1;

      

        public void ProcessRequest(HttpContext context)
         {
            throw new Exception();
          }
       
        public IAsyncResult BeginProcessRequest (HttpContext context,AsyncCallback callback,object o)

        {     
            context1 = context;

            //使用异步I/O线程时注意用下面方式建立FileStream对象,并把最后的参数userAsync设置为true
            //若文件大小小于缓冲值1024,那文件将一次性读取,回调时依然会使用CLR线程中池的工作者线程
            FileStream fileStream = new FileStream("E://My Webs/WebService1/TextFile.txt", 

                                                 FileMode.Open,FileAccess.Read,FileShare.Read, 1024, true );
            bytes = new byte[fileStream.Length];

            File file1=new File();

            file1.fileStream=fileStream;

            file1.bytes=bytes;
            return fileStream.BeginRead(file1.bytes, 0, (int)fileStream.Length, callback, file1);

            //此时,CLR线程池的工作者线程就会被及时释放,当完成读取时,再度调用IO线程完成操作。

        }

        public void EndProcessRequest(IAsyncResult result)
        {

            File file1 = (File)result.AsyncState;   
     
            file1.fileStream.EndRead(result);
            file1.fileStream.Close();    

            context1.Response.Write(System.Text.Encoding.UTF8.GetString(file1.bytes));        

             int n1,n2;

            ThreadPool.GetAvailableThreads(out n1, out n2);

            context1.Response.Write(String.Formate("WorkerThreads Count is {0}! ”+

                                           “ IOThreads Count is  {1} !",n1.ToString(),n2.ToString() ));

            //此时检测线程池,输出将会是WorkerThreads Count is 1000! IOThreads Count is 999!

            //说明异步方法使用的是IO线程 
        }

       

        public bool IsReusable {
            get {
                return false;
            }
        }

    }

    在使用WebService时,也可以使用异步调用的方式。

    http://www.pin5i.com/showtopic-10763.html

    同样对于SQL数据库,Socket,HttpWebRequest...也可使用异步进行访问。

    • DNS操作 BeginGetHostByName、BeginResolve。
    • Socket操作 BeginAccept、BeginConnect、BeginReceive等等。
    • WebRequest操作 BeginGetRequest、BeginGetResponse。
    • SqlCommand操作 BeginExecuteReader、 BeginExecuteNonQuery等等。这可能是开发一个Web应用时最常用的异步操作了。如果需要在执行数据库操作时得到IOCP支持,那么需 要在连接字符串中标记Asynchronous Processing为true(默认为false),否则在调用BeginXXX操作时就会抛出异常。

    但可惜此方式并不合适使用异步委托 ,当使用异步委托时(BeginInvoke,EndInvoke),系统所新增的线程同样来CLR线程池的工作者线程,如果麻木地使用异步方式,会适得其反,对系统的性能做成影响。

     

    ASP.NET服务器端多线程设计——异步Web服务

    ASP.NET服务器端多线程设计——异步IHttpHandler

    对 JAVA 开发有兴趣的朋友欢迎加入QQ群:174850571 共同探讨!
    对 .NET  开发有兴趣的朋友欢迎加入QQ群:162338858 共同探讨 !

  • 相关阅读:
    luogu P1833 樱花 看成混合背包
    luogu P1077 摆花 基础记数dp
    luogu P1095 守望者的逃离 经典dp
    Even Subset Sum Problem CodeForces
    Maximum White Subtree CodeForces
    Sleeping Schedule CodeForces
    Bombs CodeForces
    病毒侵袭持续中 HDU
    病毒侵袭 HDU
    Educational Codeforces Round 35 (Rated for Div. 2)
  • 原文地址:https://www.cnblogs.com/leslies2/p/1934161.html
Copyright © 2011-2022 走看看