当前位置:七道奇文章资讯网站建设网站编程
日期:2011-01-19 10:12:00  来源:本站整理

asp.net并行与多线程的理解[网站编程]

赞助商链接



  本文“asp.net并行与多线程的理解[网站编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

asp.net并行与多线程的理解

asp.net并发恳求数目影响的条件相当多,不考虑程序履行时间和能否被阻塞,它会遭到服务器tcp(普通windows服务器仿佛没限制)衔接数限制,iis衔接数限制,clr线程池对它的限制.

服务器tcp限制,[hklmsystemcurrentcontrolsetservicestcpipparameters] “enableconnectionratelimiting” =dword:00000000, 该注册表项的值改成 “0” 便可,假如是比方windows2003服务器,普通是没有这个限制的,比方我自己的2003没有.

iis衔接数限制:iis6及以下,%systemroot%system32inetsrv下的metabase.xml文件里直接改正,比方改正默许的asprequestqueuemax="3000",可以把恳求排行列队设置更大,改正默许的aspprocessorthreadmax="25",把request并发恳求线程设置更大等,具体可以参考相关资料,进程太多会设置到cpu切换线程要耗时,按照网上说法,并非越大越好,但可以综合按照并发量和系统性能相关形成设置;iis7配置的地方又不一样了,%systemroot%system32inetsrvconfigapplicationhost.config文件里改正,改正<serverruntime appconcurrentrequestlimit="5000" /> ,并发恳求限制数目,

iis manager > applicationpools > advanced settings, queue length:1000修转业列长度.hklmsystemcurrentcontrolsetserviceshttpparameters maxconnections 改正更大.

.net框架方面的限制

我认为一个asp.net程序运行起来后, 不关心差别的iis版本,它们生命逻辑不一样,iis6交给的进程之前也不一样,但我认为该进程都至少由三个线程池来管理,一个clr负责差别request恳求的工作线程池,一个io处理线程,还有该进程的非托管级的线程池,托管的这两个线程池的初始化和最大数目都可以配置和程序设置,非托管的线程池用于中转恳求给clr处理,和有io大概其他异步操作时,处理的非托管级线程.当然托管级的线程池我们是可以作一定掌握的,差别.net版本,和系统cpu数目,初始化线程池数目是不一样的,比方我目前cpu是单cpu双核系统,在.net4下一个mvc恳求中履行下面代码:

       

     int workthread = 0;
            int iothread = 0;
            threadpool.getmaxthreads(out workthread, out iothread);

获得到最大工作线程池和io线程池都为200,但假如按照相关资料,说该值为100 *cpu数目(双核也算多个cpu),windows程序中获得到的值将更大,阐明默许系统给的线程数是不一样的.

在差别.net版本中,machine.config中<processmodel autoconfig="true"/>采取默许配置,我认为应当是.net差别版本里直接写死了默许线程数目等信息,可以通过改正machine.config中该节点的一些值来到达差别的目的,默许配置的一下参数:

设置maxworkerthreaders和maxiothreads为100
设置maxconnection 为12*cpu数目
设置minfreethreads为88*cpu数目
设置minworkerthreads为50
 

最大线程数目 = (最大工作线程 * cpu数目) - 最小闲暇线程, 当然还有其他一些重要的参数.

这些都是iis6和iis7经典情势下的配置文件的改正,ii7集成情势又有点不一样了,恳求最大数目由下面决意:maxconcurrentrequestspercpu:限制每个cpu履行的恳求的数目,即便有更多的线程可用.在.net 3.5及从前的版本中,默许值是12,在.net 4中是5000.假如设为0,没有限制;maxconcurrentthreadspercpu:限制每个cpu处理恳求的线程的数目.默许值是0,没有限制.这基本上就相当于对恳求数目没有限制了,同时  <processmodel

requestqueuelimit="10000"/>   加了

表示恳求列队行列10000,在%systemroot%system32inetsrvconfigapplicationhost.config中设置,<serverruntime appconcurrentrequestlimit="10000" /> ,都是增添并行恳求限制的

看一款多线程操作代码操纵socket

首先必须包含的两个命名空间:

using system.net;

using system.net.sockets;

几个常用的类:(这些东西,查下msdn就很具体了)

iphostentry, dns,ipaddress,ipendpoint,还有最重要的socket

ipendpoint: 这个是网络终结点,很好理解,就是网络上一个固定的地址:一个ip与一个端口的组合.

下面我还是以我从前写的一个很简单的聊天程序做示例吧, (很短代码的)

form1.cs

//阐明下, 这个是集server与client与一体的.

using system;
using system.collections.generic;
using system.componentmodel;
using system.data;
using system.drawing;
using system.text;
using system.windows.forms;
using system.net;
using system.net.sockets;   //这个和上面的是利用socket必须的.
using system.io;     
using system.threading;      //这个是利用多线程必须的.

namespace onlysocket
{
    public partial class form1 : form           //partial表示这块代码只是form1类的部份, form1类担当自form类
    {
        public form1()
        {
            initializecomponent();    //构造函数, 初始化容器.
        }
        socket sock;          //定义一个socket类的对象 (默许为protected)
        thread th;             //定义一个thread类的对象
        //

        public static ipaddress getserverip()        //静态函数, 无需实例化便可调用.
        {
            iphostentry ieh = dns.gethostbyname(dns.gethostname()); //不多说了, dns类的两个静态函数

             //或用dns.resolve()替换gethostname()
            return ieh.addresslist[0];                  //返回address类的一个实例. 这里addresslist是数组并不奇特,一个server有n个ip都有大概
        }
     

        private void beginlisten()               //socket监听函数, 等下作为成立新线程的参数
        {
            ipaddress serverip = getserverip();         //调用本类静态函数getserverip得到本机ipaddress.
            ipendpoint iep = new ipendpoint(serverip, convert.toint32(tbport.text));    //本地终结点
            sock = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);   //实例化内成员sock
            byte[] bytemessage = new byte[100]; //存放消息的字节数组缓冲区, 注意数组表示办法,和c差别的.
            this.lbiep.text = iep.tostring();        
            sock.bind(iep);                                  //socket类的一个重要函数, 绑定一个ip,
            while (true)                     //这里弄了个死循环来监听端口, 有人会问死循环了,那程序不卡住了, 注意这只是个类, 这里还没有main函数呢.
            {
                try
                {
                    sock.listen(5);             //好了,sock绑定了本地终结点便可以开始监听了,5表示最大衔接数为5
                    socket newsock = sock.accept();     //这里又有socket类的一个重要的办法:accept, 该办法承受来自表面的socket衔接恳求, 并返回一个socket套接字, 这个套接字就开始处理这一个client与server之间的对话
                    newsock.receive(bytemessage); //承受client发送过来的数据保存到缓冲区.
                    string msg = "from [" + newsock.remoteendpoint.tostring() + "]:" +system.text.encoding.utf8.getstring(bytemessage)+"n";   //getstring()函数将byte数组转换为string范例.
                    rtbtalk.appendtext(msg+"n");        //显示在文本控件里
                }
                catch (socketexception se)              //捕捉非常,
                {
                    lbstate.text = se.tostring();       //将其显示出来, 在此亦可以自定义错误.
                }
            }
        }

        private void btconnect_click(object sender, eventargs e)   //衔接按钮触发的事件: 衔接server
        {
            btconnect.enabled = false;
            btstopconnect.enabled = true;
            try
            {
                th = new thread(new threadstart(beginlisten));          //成立一个新的线程专门用于处理监听,这句话可以脱离写的,比方: threadstart ts=new threadstart(beginlisten); th=new thread (ts); 不过要注意, threadstart的构造函数的参数一定如果无参数的函数. 在此函数名其实就是其指针, 这里是拜托吗?
                th.start();                            //启动线程
                lbstate.text = "listenning...";
            }
            catch (socketexception se)           //处理非常
            {
                messagebox.show(se.message, "呈现问题", messageboxbuttons.ok, messageboxicon.information);
            }
            catch (argumentnullexception ae)   //参数为空非常
            {
                lbstate.text = "参数错误";
                messagebox.show(ae.message, "错误", messageboxbuttons.ok, messageboxicon.warning);
            }

        }

        private void btstopconnect_click(object sender, eventargs e)  //终止监听
        {
            btstopconnect.enabled = false;
            btconnect.enabled = true;
            sock.close();                     //关闭套接字
            th.abort();                         //终止监听线程
          
           lbstate.text = "listenning stopped";
        }

        private void btexit_click(object sender, eventargs e)      
        {
            sock.close();
            th.abort();
            dispose();             //清理资源,就是释放内存
            this.close();          //关闭对话框, 退出程序
        }

        private void btsend_click(object sender, eventargs e)
        {
            try
            {
                ipaddress clientip = ipaddress.parse(tbtargetip.text);    //类ipaddress的静态函数parse() :将text转化为ipaddress的一个实例.
                int clientport = convert.toint32(tbport.text);                 //c#的这些转化函数很便利的,不像c++那样麻烦
                ipendpoint clientiep = new ipendpoint(clientip, clientport);     //这里用client表示不是很好....,
                byte[] byte_message;
                socket socket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);            实例化的时刻还有很多参数的, 这个是tcp的. tcp的sockettype是stream:数据流, 假如协议范例是udp, 则是数据包传送, qq就是用的udp.
                socket.connect(clientiep); //socket的又一个函数connect(ipendpoint) .衔接远程套接字
                byte_message = system.text.encoding.utf8.getbytes(rtbwords.text); //发现utf8可支持中文,就用之
                socket.send(byte_message);
                rtbtalk.appendtext("n"+"my words:" + rtbwords.text + "n");
                socket.shutdown(socketshutdown.both);
                socket.close();
            }
            catch (argumentnullexception ae)
            {
                messagebox.show(ae.message,"参数为空",messageboxbuttons.okcancel,messageboxicon.information);
            }
            catch (socketexception se)
            {
                messagebox.show(se.message, "呈现问题", messageboxbuttons.ok, messageboxicon.information);
            }
        }
      
    }
}

program.cs

using system;
using system.collections.generic;
using system.windows.forms;

namespace onlysocket
{
    static class program
    {
        /// <summary>
        /// 利用程序的主进口点.
        /// </summary>
        [stathread]
        static void main()        //这儿才是main函数

        {
            application.enablevisualstyles();
            application.setcompatibletextrenderingdefault(false);
            application.run(new form1());
        }
    }
}


 

写了半天了, 够累的了, 固然都是很底子的东西, 我自己写的时刻也复习了一边 , 呵呵.

其实多线程我自己也不是很纯熟, 记得去年暑假写过一个多线程扫描器, 也不知为啥, 线程开到50以上就非常, 很忧郁的. 其实当时我就是用的new thread=thread(new threadstart(fun))实现的, 办法感受很拙笨,呵呵.

大致代码仿佛是这样的吧:

先写个scan类:

public class scan

{

try{ public scan(){   ...init...   }

            public void scan{ ..task循环扫描... } //task构造体里面有ip, 端口, 能否已扫描标志flag}

catch{}

}

然后主函数里面可以这样搞:

scan[] scanner = new scan[xx]

thread[] thread = new thread[xx];
            for (int i = 0; i < xx;i++)
            {
                scanner[i] = new scan(this, i);
                thread[i] = new thread(new threadstart(scanner[i].startscan));
                thread[i].start();

            }

其实这样便可以简单的实现多线程了.


  以上是“asp.net并行与多线程的理解[网站编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • ASP利用正则表达式提取内容
  • nginx 反向代理iis支持 ASP脚本设置
  • <b>ASP.NET安全设置防备ASPXSpy</b>
  • Ubuntu Server+Apache 运行 asp.net
  • 怎样ASP.NET MVC调用Delphi开辟的Web报表
  • 学习ASP.NET需求举行的步骤办法
  • ASP.NET脚本过滤-避免跨站脚本攻击
  • Asp WinHttp.WinHttpRequest.5.1 对象利用详解
  • ASP防XSS注入函数
  • Asp 防备CC攻击模块 (Anti-CC.asp)
  • metasploit metasploit 中文系统安装失利问题
  • Ubuntu 11下安装Metasploit Pro 4.0.0
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .