苏飞—Perky Su

签名: 软件开发,功能定制,全国各种接口开发,网页抓取程序,请联系我给我留言      Q Q:                    

posts - 184, comments - 1667, trackbacks - 3, articles - 5
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

源代码下载:http://download.csdn.net/detail/sufei1013/4017086  没有分的可以留下信箱我统一发给大家

引言


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

程序员在写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);
}

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

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

 

   /// <summary>
/// 创建表格
/// </summary>
/// <param name="rows">生成多少行数</param>
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.定义一个方法用来访问指定的网站就是我们的实际测试这块,

一起来看下代码

 /// <summary>
/// 执行数据
/// </summary>
/// <param name="dgvrowid"> 线程号行号</param>
/// <param name="number">循环总次数</param>
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方法,是用来异步执行委托的,系统自带方法。

  upDateStateDelegate是要执行的委托我们前面有定义

 ExecDateDiff计算时间差的方法自己写的如下代码

 /// <summary>
/// 程序执行时间测试
/// </summary>
/// <param name="dateBegin">开始时间</param>
/// <param name="dateEnd">结束时间</param>
/// <returns>返回(秒)单位,比如: 0.00239秒</returns>
public static string ExecDateDiff(DateTime dateBegin, DateTime dateEnd)
{
TimeSpan ts1 = new TimeSpan(dateBegin.Ticks);
TimeSpan ts2 = new TimeSpan(dateEnd.Ticks);
TimeSpan ts3 = ts1.Subtract(ts2).Duration();
return ts3.TotalMilliseconds.ToString();
}

   注意,大家一定要记着这里的类型要和委托的类型是一样的,否则为出错,而且它不会自动转化,如果你定义的是String,传的是int是不可以的, 要手动的去转,这点请大家注意一下。


 dgvrowid启动线程所在DataGridview行,一行是一个线程的变化情况

 "总用时(毫秒)" 列名,这里是为了方便 大家看,使用的汉语大家见谅。

6.启动线程,我们只要执行一个For就可以循环启动了,大家一起来看看方法吧,

 private void button3_Click(object sender, EventArgs e)
{
int count = Convert.ToInt32(txtCount.Text.Trim());
int number = Convert.ToInt32(txtNumber.Text.Trim());
CreateTable(count + 1);
//开启number个线程
for (int i = 0; i < count; i++)
{
Thread pingTask = new Thread(new ThreadStart(delegate
{
PingTask(i, number);
}));
pingTask.Start();
Thread.Sleep(100);
}
}

我们都知道线程是不能直接传参数的,只能传Object,但使用匿名委托就可以解决 这个问题,方法如上面,大家看不明白的可以留言给我。

Thread.Sleep(100); 是为了让线程正常启动做了一个时间间隔。

大家可以根据自己的情况调整

 

其实这个例子不但可以实现这样测试,大家还可以用来访问数据库,开上几千个线程,看看你的Sql代码访问速度有多快。

个人感觉很不错的一种压力测试方法

希望大家多提提建议哦

    

   

-------------------------------------------------------------签名部分------------------------------------------------------------------------

                          

         欢迎大家转载,如有转载请注明文章来自:   http://sufei.cnblogs.com/   

签名:做一番一生引以为豪的事业;在有生之年报答帮过我的人;并有能力帮助需要帮助的人;    

软件开发,功能定制,请联系我给我留言 QQ:361983679 Email:sufei.1013@163.com  MSN:sufei.1013@163.com 


-------------------------------------------------------------------推荐文章--------------------------------------------------------------
1.C#仿QQ皮肤 2.Sql2005学习笔记 3.httpHelper类

Feedback

#1楼  回复 引用 查看   

2012-01-12 12:34 by 农村的芬芳      
。。。有必要吗?有一大堆的专业测压工具,
性能跟好多有关的,
硬件,软件,数据库,硬盘IO,CPU,SQL语句,程序。。。。。。等等

#2楼  回复 引用 查看   

2012-01-12 12:36 by 阳光沙滩海岸线      
用loadrunner

#3楼[楼主]  回复 引用 查看   

2012-01-12 12:37 by 苏飞      
@农村的芬芳
测试是次要,关键是多线程,不过也不失为一种手段

#4楼  回复 引用 查看   

2012-01-12 12:39 by 农村的芬芳      
所有的性能测试工具,肯定都会模似多用户并发的........

#5楼[楼主]  回复 引用 查看   

2012-01-12 12:50 by 苏飞      
@农村的芬芳
这个我知道,而且也一直在用,这不过是个例子,最少是自己写的,知道是怎么个情况。

#6楼  回复 引用 查看   

2012-01-12 12:55 by 小赖同学      
自己写也有好处的,楼主可否发一份源码给我,我在CSDN上没分了,我也想看看这个多线程,谢谢楼主了,mylxccxl@163.com

#7楼  回复 引用 查看   

2012-01-12 12:58 by duwamish      
13579981@qq.com 大作留名

#8楼[楼主]  回复 引用 查看   

2012-01-12 12:59 by 苏飞      
@小赖同学
http://files.cnblogs.com/sufei/AutoFor.zip

#9楼[楼主]  回复 引用 查看   

2012-01-12 13:00 by 苏飞      
@duwamish
http://files.cnblogs.com/sufei/AutoFor.zip

#10楼  回复 引用 查看   

2012-01-12 13:44 by ajunfly      
ajunflying@126.com发一份 谢了

#11楼[楼主]  回复 引用 查看   

2012-01-12 13:45 by 苏飞      
@ajunfly
看你楼上地址

#12楼  回复 引用 查看   

2012-01-12 16:59 by 爱婚      
请发一份给我,谢谢
heshanch@163.com

#13楼[楼主]  回复 引用 查看   

2012-01-12 17:29 by 苏飞      
@爱婚
http://files.cnblogs.com/sufei/AutoFor.zip

#14楼  回复 引用 查看   

2012-01-12 17:46 by 深邃的狮子座      
楼主这个测了这么看出好坏呢?我是菜鸟。

#15楼[楼主]  回复 引用 查看   

2012-01-12 17:56 by 苏飞      
@深邃的狮子座
看访问速度,是否是你想要的,就是时间差

#16楼  回复 引用 查看   

2012-01-13 11:39 by 施之贵      
楼主你这个要测试哪个网站呢?网站地址不会在代码中写死了吧?

#17楼[楼主]  回复 引用 查看   

2012-01-13 11:57 by 苏飞      
@施之贵
兄弟我分享的就是代码,是写在代码里面的,没有配置 ,不过如果你感觉不方便 的话可以自己修改一下,呵呵,这个只不过是多传个参数的问题?

#18楼  回复 引用 查看   

2012-01-13 23:05 by 施之贵      
呵呵……先学习学习
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 2320430 t6fZq/qylM8=