請穩步我的博客查閱並下載所有資源以及源代碼 http://www.cckan.net
我們一直在做網站,但在我河南這塊,對測試工作,特別是壓力測試一般都不怎麼在意,都是自己訪問一下速度不錯就行了,再就是數據庫訪問速度測試也是同樣情況
程序員在寫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:[email protected] MSN:[email protected]
-------------------------------------------------------------------推薦文章--------------------------------------------------------------