C#多线程|匿名委托传参数|测试您的网站能承受的压力|附源代码

发表于:2012-02-14来源:博客园作者:Perky Su点击数: 标签:C#
我们一直在做网站,但在我河南这块,对测试工作,特别是压力测试一般都不怎么在意,都是自己访问一下速度不错就行了,再就是数据库访问速度测试也是同样情况 程序员在写Sql代码时,一般是一个人写完之后,一运行可快完事

  我们一直在做网站,但在我河南这块,对测试工作,特别是压力测试一般都不怎么在意,都是自己访问一下速度不错就行了,再就是数据库访问速度测试也是同样情况

  程序员在写Sql代码时,一般是一个人写完之后,一运行可快完事

  其实这些是不够的,我们根本没有进行过多用户多线程的测试,如果是100个,一千个要同时访问,还会有这样的速度吗?

  我们自己反思一下是不是有这样的经历呢,我做的网站刚上传服务器,打开很快,调数据库1000条以内一秒用不了,感觉非常好,但过了不几天,就会感觉到网站很慢很慢,于是去检查测试

  其实这些可以提前做的,我下面来实现一个多线程测试网站访问速度的功能。

  效果

  说明:

  1.一次可以开N多个线程;

  2.可以设置要访问的地址;

  3.可以设置要循环访问的次数;

  相关技术点:

  1.C# Winform;

  2.httpHelper类;这是我之前自己写的一个类,大家可以参考一下(带证书,无视编码,设置代理等)

  3.多线程;

  4.线程之间的传参;

  5.委托与匿名委托的使用方法;

  实现步骤:

  1.新建一个CS项目,AutoFor,新建一个窗体为TextFor

  2.自己拉几个控件实现如下界面

  3.定义一个委托用来修改DataGridview的值,代码如下

  //修改表格的委托 private delegate void UpDateDgvDelegate(string msg, int rowId, string columnName); private UpDateDgvDelegate _upDateStateDelegate; //构造器 public TextFor() { InitializeComponent(); _upDateStateDelegate = new UpDateDgvDelegate(UpDateDgv); } ///

/// 修改表格的行数据 /// ///要修改为的数据 ///行号 ///列名 private void UpDateDgv(string msg, int rowId, string columnName) { try { dgvTextFor.Rows[rowId].Cells[columnName].Value = msg.ToString(); } catch { } }

  复制代码

  4.在单击开始时先生成对应的线程表格式,就是界面上的DataGridview,大家看下代码

  ///

/// 创建表格 /// ///生成多少行数 private void CreateTable(int rows) { DataTable dt_Sale = new DataTable(); DataColumn dc = null; //线程ID dc = new DataColumn(); dc.ColumnName = "线程ID"; dc.DefaultValue = "1"; dc.DataType = Type.GetType("System.String"); dt_Sale.Columns.Add(dc); //循环类型 dc = new DataColumn(); dc.ColumnName = "循环类型"; dc.DefaultValue = " "; dc.DataType = Type.GetType("System.String"); dt_Sale.Columns.Add(dc); //当前循环次数 dc = new DataColumn(); dc.ColumnName = "当前循环次数"; dc.DefaultValue = " "; dc.DataType = Type.GetType(" System.String"); dt_Sale.Columns.Add(dc); //开始时间 dc = new DataColumn(); dc.ColumnName = "开始时间"; dc.DefaultValue = " "; dc.DataType = Type.GetType("System.String"); dt_Sale.Columns.Add(dc); //结束时间 dc = new DataColumn(); dc.ColumnName = "结束时间"; dc.DefaultValue = " "; dc.DataType = Type.GetType("System.String"); dt_Sale.Columns.Add(dc); //总用时(毫秒) dc = new DataColumn(); dc.ColumnName = "总用时(毫秒)"; dc.DefaultValue = " "; dc.DataType = Type.GetType("System.String"); dt_Sale.Columns.Add(dc); DataRow dr = dt_Sale.NewRow(); for (int i = 1; i < rows; i++) { dr["线程ID"] = i.ToString(); dr["循环类型"] = "For循环"; dr["当前循环次数"] = "0"; dr["开始时间"] = "00:00:00"; dr["结束时间"] = "00:00:00"; dr["总用时(毫秒)"] = "0"; dt_Sale.Rows.Add(dr); dr = dt_Sale.NewRow(); } dgvTextFor.DataSource = dt_Sale; }

  复制代码

  5.定义一个方法用来访问指定的网站就是我们的实际测试这块,

  一起来看下代码

  ///

/// 执行数据 /// ///线程号行号 ///循环总次数 private void PingTask(int dgvrowid, int number) { //获取开始时间 DateTime st = DateTime.Now; //开始时间 this.BeginInvoke(_upDateStateDelegate, st.ToString("hh-mm-ss"), dgvrowid, "开始时间"); for (int i = 0; i < number; i++) { try { HttpHelps hh = new HttpHelps(); //自动访问百度,主要是延长时间 hh.GetHttpRequestStringByNUll_Get("www.baidu.com", null); //当前循环次数 this.BeginInvoke(_upDateStateDelegate, i.ToString(), dgvrowid, "当前循环次数"); //获取结束时间 DateTime et = DateTime.Now; //结束时间 this.BeginInvoke(_upDateStateDelegate, et.ToString("hh-mm-ss"), dgvrowid, "结束时间"); //总用时(毫秒) this.BeginInvoke(_upDateStateDelegate, ExecDateDiff(st, et), dgvrowid, "总用时(毫秒)"); } catch { } } }

  复制代码

  我来解释下这句 //总用时(毫秒) this.BeginInvoke(_upDateStateDelegate, ExecDateDiff(st, et), dgvrowid, "总用时(毫秒)");

  第一个BeginInvoke方法,是用来异步执行委托的,系统自带方法。

原文转自:http://www.ltesting.net