Commit d416d82d authored by 罗显健's avatar 罗显健

wMuiltTaskSimulate 增加消息显示。

parent 7ed9a8f5
using System;
namespace Tools.MyUtils
{
/// <summary>
/// 时间监视
/// </summary>
public class TimeWatch
{
private DateTime? dtStart, dtEnd;
/// <summary>
/// 构造函数
/// </summary>
private TimeWatch()
{
ReStart();
}
#region 公共操作
/// <summary>
/// 停止监视
/// </summary>
public void Stop()
{
dtEnd = DateTime.Now;
}
/// <summary>
/// 重启监视
/// </summary>
public void ReStart()
{
dtStart = DateTime.Now;
dtEnd = null;
}
/// <summary>
/// 时间间隔
/// </summary>
public TimeSpan TimeSpan
{
get
{
return (TimeSpan)((dtEnd == null ? DateTime.Now : dtEnd) - dtStart);
}
}
#endregion
#region 静态方法
/// <summary>
/// 启动一个新的监视
/// </summary>
/// <returns></returns>
public static TimeWatch Start()
{
return new TimeWatch();
}
/// <summary>
/// 写控制台测试日志
/// </summary>
/// <param name="name"></param>
/// <param name="action"></param>
public static void Wrap(string name, Action action)
{
var watch = Start();
action();
ShowTime(name, watch);
}
/// <summary>
/// 控制台显示测试时长,单位:毫秒
/// </summary>
/// <param name="name"></param>
/// <param name="timeWatch"></param>
private static void ShowTime(string name, TimeWatch timeWatch)
{
Console.WriteLine($"【{name}】:{timeWatch.TimeSpan.TotalMilliseconds} ms");
}
#endregion
}
}
......@@ -7,6 +7,7 @@ using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
//
using System.Windows.Forms;
......@@ -325,6 +326,63 @@ namespace Tools.MyUtils
action();
}
#region 跨线程相关操作
/// <summary>
/// 在主线程里执行一个动作
/// </summary>
/// <param name="owner">执行动作的控件</param>
/// <param name="action">执行的动作</param>
/// <param name="objData">传递给指定动作的参数</param>
public static void DoMainAsync(Control owner, Action<object> action, object objData)
{
new TaskFactory().StartNew(obj =>
{
var dataDo = (DoMainData)obj;
if (dataDo.Control != null && !dataDo.Control.IsDisposed && !dataDo.Control.Disposing)
dataDo.Control?.Invoke(action, dataDo.Data);
}, new DoMainData { Control = owner, Data = objData });
}
/// <summary>
/// 在主线程里执行一个动作
/// </summary>
/// <param name="owner">执行动作的控件</param>
/// <param name="action">执行的动作</param>
public static void DoMainAsync(Control owner, Action action)
{
new TaskFactory().StartNew(obj =>
{
var dataDo = (DoMainData)obj;
if (dataDo.Control != null && !dataDo.Control.IsDisposed && !dataDo.Control.Disposing)
dataDo.Control?.Invoke(action);
}, new DoMainData { Control = owner });
}
/// <summary>
/// 跨线程参数结构
/// </summary>
struct DoMainData
{
/// <summary>
/// 跨线程操作的主控件
/// </summary>
public Control Control;
/// <summary>
/// 参数
/// </summary>
public object Data;
}
#endregion
#endregion
#region 数据库链接处理
......@@ -861,7 +919,8 @@ namespace Tools.MyUtils
{
var result = new List<string>();
dt.Columns.Cast<DataColumn>().ToList()
.ForEach(c => {
.ForEach(c =>
{
if (!c.AutoIncrement)
{
result.Add(c.ColumnName);
......@@ -933,6 +992,6 @@ namespace Tools.MyUtils
}
#endregion
}
}
......@@ -112,6 +112,7 @@
<Compile Include="MyUtils\DrawHelper.cs" />
<Compile Include="MyUtils\InputtingService.cs" />
<Compile Include="MyUtils\SegPicture.cs" />
<Compile Include="MyUtils\TimeWatch.cs" />
<Compile Include="UI\sys\wLogin.cs">
<SubType>Form</SubType>
</Compile>
......
......@@ -40,12 +40,13 @@
this.label2 = new System.Windows.Forms.Label();
this.txtAssembly = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.txtMsg = new System.Windows.Forms.TextBox();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// btnStart
//
this.btnStart.Location = new System.Drawing.Point(458, 27);
this.btnStart.Location = new System.Drawing.Point(431, 10);
this.btnStart.Name = "btnStart";
this.btnStart.Size = new System.Drawing.Size(75, 23);
this.btnStart.TabIndex = 0;
......@@ -56,7 +57,7 @@
// lblTimes
//
this.lblTimes.AutoSize = true;
this.lblTimes.Location = new System.Drawing.Point(43, 29);
this.lblTimes.Location = new System.Drawing.Point(16, 12);
this.lblTimes.Name = "lblTimes";
this.lblTimes.Size = new System.Drawing.Size(77, 12);
this.lblTimes.TabIndex = 1;
......@@ -64,14 +65,14 @@
//
// txtTimes
//
this.txtTimes.Location = new System.Drawing.Point(122, 26);
this.txtTimes.Location = new System.Drawing.Point(95, 9);
this.txtTimes.Name = "txtTimes";
this.txtTimes.Size = new System.Drawing.Size(100, 21);
this.txtTimes.TabIndex = 2;
//
// txtWorks
//
this.txtWorks.Location = new System.Drawing.Point(316, 26);
this.txtWorks.Location = new System.Drawing.Point(289, 9);
this.txtWorks.Name = "txtWorks";
this.txtWorks.Size = new System.Drawing.Size(100, 21);
this.txtWorks.TabIndex = 4;
......@@ -79,7 +80,7 @@
// lblWorks
//
this.lblWorks.AutoSize = true;
this.lblWorks.Location = new System.Drawing.Point(237, 29);
this.lblWorks.Location = new System.Drawing.Point(210, 12);
this.lblWorks.Name = "lblWorks";
this.lblWorks.Size = new System.Drawing.Size(77, 12);
this.lblWorks.TabIndex = 3;
......@@ -93,7 +94,7 @@
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Controls.Add(this.txtAssembly);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Location = new System.Drawing.Point(45, 65);
this.groupBox1.Location = new System.Drawing.Point(18, 41);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(497, 136);
this.groupBox1.TabIndex = 5;
......@@ -148,11 +149,24 @@
this.label1.TabIndex = 3;
this.label1.Text = "程序集:";
//
// txtMsg
//
this.txtMsg.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtMsg.Location = new System.Drawing.Point(18, 183);
this.txtMsg.Multiline = true;
this.txtMsg.Name = "txtMsg";
this.txtMsg.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtMsg.Size = new System.Drawing.Size(500, 178);
this.txtMsg.TabIndex = 6;
//
// wMuiltTaskSimulate
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(591, 222);
this.ClientSize = new System.Drawing.Size(544, 379);
this.Controls.Add(this.txtMsg);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.txtWorks);
this.Controls.Add(this.lblWorks);
......@@ -182,5 +196,6 @@
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox txtAssembly;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox txtMsg;
}
}
\ No newline at end of file
......@@ -5,6 +5,8 @@ using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tools.MyCommon;
using Tools.MyUtils;
namespace Tools.UI
{
......@@ -13,8 +15,8 @@ namespace Tools.UI
/// </summary>
public partial class wMuiltTaskSimulate : wBasic
{
static wMuiltTaskSimulate wInstance;
int totalTimes = 0, maxWorks = 0;
public wMuiltTaskSimulate()
{
......@@ -30,51 +32,21 @@ namespace Tools.UI
txtWorks.Text = "5";
}
int totalTimes = 0, maxWorks = 0;
private void Run(Action callBack)
{
int finishCount = 0;
Task.Run(() =>
{
Parallel.For(0, totalTimes, new ParallelOptions { MaxDegreeOfParallelism = maxWorks }, i =>
{
try
{
ShowMsg($"准备执行第{i}任务");
Execute(txtAssembly.Text, txtClass.Text, txtMethod.Text);
ShowMsg($"第{i}任务执行完成!");
}
catch (Exception ex)
{
ShowMsg(ex.Message);
}
finally
{
Interlocked.Increment(ref finishCount);
if (finishCount >= totalTimes) MyUtils.Utils.AsyncUI(wInstance, () => callBack());
}
});
});
}
private void btnStart_Click(object sender, EventArgs e)
{
if (!CheckData()) return;
if (!CheckInputData()) return;
txtMsg.Clear(); // 每次执行前都清除一遍
btnStart.Enabled = false;
Run(() => btnStart.Enabled = true);
}
private bool CheckData()
/// <summary>
/// 校验输入
/// </summary>
/// <returns></returns>
private bool CheckInputData()
{
if (!int.TryParse(txtTimes.Text, out totalTimes) || totalTimes < 0)
{
......@@ -91,39 +63,107 @@ namespace Tools.UI
return true;
}
/// <summary>
/// 功能主要操作入口
/// </summary>
/// <param name="completedCallBack">所有操作执行完成之后的回调</param>
private void Run(Action completedCallBack)
{
int finishCount = 0;
Task.Run(() =>
{
Parallel.For(0, totalTimes, new ParallelOptions { MaxDegreeOfParallelism = maxWorks }, i =>
{
try
{
Execute(txtAssembly.Text, txtClass.Text, txtMethod.Text, i);
}
catch (Exception ex)
{
Utils.DoMainAsync(wInstance, ShowMsg, $"执行操作失败:{ex.Message}");
}
finally
{
Interlocked.Increment(ref finishCount);
// 回调、只有在所有的操作都执行完(无论成功与否)的时候调用。
if (finishCount >= totalTimes)
{
Utils.DoMainAsync(wInstance, completedCallBack);
}
}
});
});
}
/// <summary>
/// 执行计划任务。
/// 执行计划任务
/// </summary>
/// <returns></returns>
/// <param name="dllName"></param>
/// <param name="className"></param>
/// <param name="methodName"></param>
/// <param name="taskNo"></param>
/// <exception cref="Exception"></exception>
public void Execute(string dllName, string className, string methodName)
public void Execute(string dllName, string className, string methodName, int taskNo)
{
var assembly = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, dllName);
if (!File.Exists(assembly)) throw new Exception($"程序集[{dllName}]不存在");
var type = Assembly.LoadFrom(assembly).GetType(className);
if (type == null) throw new Exception($"程序集[{dllName}]中不存在业务类[{className}]");
var method = type.GetMethod("RunDapper");
var method = type.GetMethod(methodName);
if (method == null) throw new Exception($"程序集[{dllName}]-[{className}]类中不存在[{methodName}]方法或重载");
var objInstance = Activator.CreateInstance(type);
ShowMsg($"任务执行、当前线程:{Thread.CurrentThread.ManagedThreadId}");
Utils.DoMainAsync(wInstance, ShowMsg, $"任务构建完成,准备执行。当前线程:{Thread.CurrentThread.ManagedThreadId},任务编号:{taskNo}");
method.Invoke(objInstance, null);
TimeWatch timeWatch = TimeWatch.Start();
try
{
method.Invoke(objInstance, null);
Utils.DoMainAsync(wInstance, ShowMsg, $"任务执行完成、耗时:{timeWatch.TimeSpan.TotalMilliseconds} (毫秒),任务编号:{taskNo}");
}
catch (Exception ex)
{
Utils.DoMainAsync(wInstance, ShowMsg, $"任务:{taskNo}执行失败、耗时:{timeWatch.TimeSpan.TotalMilliseconds} (毫秒),原因:{GetAllMessage(ex)}");
}
}
/// <summary>
/// 获取异常所有消息
/// </summary>
/// <param name="ex"></param>
/// <returns></returns>
private string GetAllMessage(Exception ex)
{
return (ex.InnerException == null) ? ex.Message : ex.Message + "-->" + GetAllMessage(ex.InnerException);
}
#region 显示消息
/// <summary>
/// 显示消息
/// </summary>
/// <param name="content"></param>
private void ShowMsg(string content)
{
Console.WriteLine(content);
txtMsg.AppendText(content);
txtMsg.AppendText("\r\n");
}
/// <summary>
/// 显示消息
/// </summary>
/// <param name="strObj"></param>
private void ShowMsg(object strObj) => ShowMsg(strObj.ToString());
#endregion
}
}
......@@ -117,4 +117,46 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="btnStart.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="lblTimes.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="txtTimes.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="txtWorks.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="lblWorks.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="groupBox1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="txtMethod.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="label3.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="txtClass.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="label2.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="txtAssembly.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="label1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="txtMsg.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>
\ No newline at end of file
......@@ -60,7 +60,7 @@ namespace Tools
this.CreateModule(Tools_dev, typeof(UI.wModuleManager), "模块管理", "tr:系统模块管理工具(支持生成SQL)"),
this.CreateModule(Tools_dev, typeof(UI.wDbAnlysis), "SQL效率分析", "tr:用于分析SQL查询效率(执行计划和IO计数)"),
this.CreateModule(Tools_dev, typeof(UI.wSysChecker), "检查配置工具", "tr:系统通用检查配置服务(通过存储过程检查)"),
this.CreateModule(Tools_dev, typeof(UI.wMuiltTaskSimulate), "批量并行任务模拟", "tr:多线程并行运行指定测试项目,用来做压力性能测试等。。。"),
this.CreateModule(Tools_dev, typeof(UI.wMuiltTaskSimulate), "批量并行任务模拟", "lxj:多线程并行运行指定测试项目,用来做压力性能测试等。。。"),
//-------------------------------
this.CreateModule(Tools_human, typeof(UI.wUser), "员工管理", "tr:员工状态及头像管理"),
this.CreateModule(Tools_human, typeof(UI.wEvaluationOfEmployee), "员工考核", "tr:员工考核的记录工具"),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment