using CSFramework.DB; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace CSFramework.DBTester { /// /// C/S框架网,CSFramework.DB,C/S框架数据库并发测试 /// public partial class frmSQLConcurrentTester : Form { static object _threadCount = 0;//线程数量 static object _connCount = 0;//已建立的SQL连接数 static List _threadList = new List();//线程数量 static DateTime _startTime = DateTime.Now; static List _DocNos = new List();//本次测试生成的单据号码 static object _ThreadFinish = 0; static object _Rows_Inserted = 0; static object _Rows_Updated = 0; static object _Rows_Deleted = 0; static object _Failed = 0; public frmSQLConcurrentTester() { InitializeComponent(); } private void btnTest_Click(object sender, EventArgs e) { txtResult.Text = ""; OnResult("开始测试..."); btnTest.Enabled = false; _connCount = 0; _threadCount = 0; _Failed = 0; _ThreadFinish = 0; _Rows_Inserted = 0; _Rows_Updated = 0; _Rows_Deleted = 0; _startTime = DateTime.Now; _DocNos.Clear(); //初始化进度条 this.DoPrepareProgress(); //启动多线程 int t = int.Parse(txtThreads.Text); int count = 1; while (count <= t) { Task.Run(() => { DoThread(); }); Application.DoEvents(); count++; } //等待全部线程完成处理 Thread.Sleep(1000); //必须等待第1个线程 WaitThreads(); OnResult($"本次测试用户数据, Insert={_Rows_Inserted},Update={_Rows_Updated},Delete={_Rows_Deleted},失败数={_Failed}"); OnResult("测试结束..."); TimeSpan ts = DateTime.Now - _startTime; lblTime.Text = "用时:" + ts.TotalSeconds.ToString() + "秒."; btnTest.Enabled = true; btnTest.Invalidate(); GC.Collect();//回收垃圾 } /// /// 等待线程 /// private void WaitThreads() { while (int.Parse(_ThreadFinish.ToString()) < int.Parse(txtThreads.Text)) { //处理线程.... Application.DoEvents(); } } /// /// 启动一个线程 /// private void DoThread() { try { //线程任务计数器 lock (_threadCount) { _threadCount = int.Parse(_threadCount.ToString()) + 1; } int currentID = int.Parse(_threadCount.ToString()); if (currentID > int.Parse(txtThreads.Text)) return; lock (_threadList) _threadList.Add(currentID); this.Invoke(new SyncCall(this.OnResult), new object[] { "开始线程:" + currentID.ToString() }); string connStr = ""; //本地连接 if (rbConnLocal.Checked) connStr = "Server =.; Database = CSFrameworkV5_Normal; User ID = sa; Password = test;"; else//远程连接 connStr = "Server =120.77.22.34; Database = CSFrameworkV5_Normal; User ID = sa; Password = test;"; //启动线程池 if (chkPooling.Checked) connStr = connStr + "pooling = true; connection lifetime = 0; min pool size = 1; max pool size = 32767"; else connStr = connStr + "pooling = false; "; string SQL = "INSERT INTO tb_QO(QONO,DocDate,CustomerCode,RefPONO,Currency,Sales,CreationDate,CreatedBy,LastUpdateDate,LastUpdatedBy)" + "VALUES(@QONO, @DocDate, @CustomerCode, @RefPONO, @Currency, @Sales, @CreationDate, @CreatedBy, @LastUpdateDate, @LastUpdatedBy)"; string SQL1 = "UPDATE tb_QO SET Client=@Client,Remark=@Remark,LastUpdateDate=@LastUpdateDate WHERE QONO=@QONO"; string SQL2 = "DELETE tb_QO WHERE QONO=@QONO"; int sub_total = 0; int go = 0; CommandHelper cmd = null; while (int.Parse(_connCount.ToString()) < int.Parse(txtConns.Text)) { //锁定连接数计时器+1 lock (_connCount) { _connCount = int.Parse(_connCount.ToString()) + 1; if (int.Parse(_connCount.ToString()) > int.Parse(txtConns.Text)) break; } IDatabase db = DatabaseFactory.CreateDatabase(DatabaseType.SqlServer, connStr); //抽签,go<=10,模拟1个用户新增一条数据 // go>10<=20,模拟1个用户随机更新一条数据 // go>=20,模拟1个用户随机删除一条数据 Thread.Sleep(100); go = new Random().Next(1, 30); //新增记录 if (go <= 10 || _DocNos.Count < 1) { cmd = db.CreateCommand(SQL); cmd.AddParam("@QONO", GetDocNo()); cmd.AddParam("@DocDate", DateTime.Now); cmd.AddParam("@CustomerCode", DateTime.Now.ToString("yyyyMMddHHmmssfff")); cmd.AddParam("@RefPONO", DateTime.Now.ToString("yyyyMMddHHmmssfff")); cmd.AddParam("@Currency", "RMB"); cmd.AddParam("@Sales", "admin"); cmd.AddParam("@CreationDate", DateTime.Now); cmd.AddParam("@CreatedBy", "admin"); cmd.AddParam("@LastUpdatedBy", "admin"); cmd.AddParam("@LastUpdateDate", DateTime.Now); int i = db.ExecuteCommand(cmd.Command); if (i > 0) { //执行命令:处理的记录数 lock (_Rows_Inserted) { _Rows_Inserted = int.Parse(_Rows_Inserted.ToString()) + 1; } } } //修改记录 if (go > 10 && go <= 20) { cmd = db.CreateCommand(SQL1); cmd.AddParam("@QONO", GetDocNoExists()); cmd.AddParam("@Client", "csframework.com"); cmd.AddParam("@Remark", "用户更新了数据"); cmd.AddParam("@LastUpdateDate", DateTime.Now); int i = db.ExecuteCommand(cmd.Command); //执行命令:处理的记录数 lock (_Rows_Updated) { _Rows_Updated = int.Parse(_Rows_Updated.ToString()) + 1; } } //删除记录 if (go > 20 && go <= 30) { cmd = db.CreateCommand(SQL2); cmd.AddParam("@QONO", GetDocNoExists()); //执行命令:处理的记录数 int i = db.ExecuteCommand(cmd.Command); lock (_Rows_Deleted) { _Rows_Deleted = int.Parse(_Rows_Deleted.ToString()) + 1;//仅统计删除成功的记录 } } sub_total++; if (cmd != null) cmd.Command.Dispose(); db = null; //通知处理1次 this.Invoke(new SyncCall(this.OnProgress), new object[] { 1 }); } lock (_threadList) _threadList.Remove(currentID); lock (_ThreadFinish) _ThreadFinish = int.Parse(_ThreadFinish.ToString()) + 1; //通知事件:线程处理完成 this.Invoke(new SyncCall(this.OnResult), new object[] { $"线程<{currentID}>结束,共处理:{sub_total}个SQL连接!" }); Application.DoEvents(); } catch (Exception ex) { this.Invoke(new SyncCall(this.OnResult), new object[] { "错误:" + ex.Message }); lock (_ThreadFinish) _ThreadFinish = int.Parse(_ThreadFinish.ToString()) + 1; lock (_Failed) _Failed = int.Parse(_Failed.ToString()) + 1; } } private string GetDocNoExists() { lock (_DocNos) { int i = new Random().Next(1, _DocNos.Count); return _DocNos[i - 1]; } } /// /// 初始化进度条 /// private void DoPrepareProgress() { lblProgress.Text = "0/0"; pb.Minimum = 0; pb.Maximum = int.Parse(txtConns.Text); pb.Value = 0; } /// /// 获取单据号码 /// /// private string GetDocNo() { Thread.Sleep(5); var docNo = DateTime.Now.ToString("yyyyMMddHHmmssfff") + Guid.NewGuid().ToString().ToLower().Replace("-", "").Substring(0, 10); lock (_DocNos) { _DocNos.Add(docNo); } return docNo; } /// /// 显示结果信息 /// /// private void OnResult(object value) { string text = value.ToString(); txtResult.AppendText(text + "\r\n"); txtResult.ScrollToCaret(); if (text.IndexOf("开始线程") >= 0) txtRunThreads.Text = _threadCount.ToString(); } /// /// 更新进度条 /// /// private void OnProgress(object value) { if (pb.Value + 1 <= pb.Maximum) { pb.Value++; lblProgress.Text = pb.Value.ToString() + "/" + pb.Maximum.ToString(); TimeSpan ts = DateTime.Now - _startTime; lblTime.Text = "用时:" + ts.TotalSeconds.ToString() + "秒."; } else { } } } /// /// 异步调用过程 /// /// public delegate void SyncCall(object value); }