Red*_*dax 13 c# optimization performance event-handling winforms
我有性能问题.我创建了100个新按钮,我想分配一个Click事件处理程序.我执行此代码大约100次:
Buttons[i].Button.Click += new System.EventHandler(Button_Click);
Run Code Online (Sandbox Code Playgroud)
完成大约需要2秒.我在同一个函数中有很多其他事件赋值,但它们只需要几毫秒来执行.所以我已经改变了我的代码
Buttons[i].Button.MouseUp += new System.Windows.Forms.MouseEventHandler(Button_Click);
Run Code Online (Sandbox Code Playgroud)
现在代码很快(一些毫秒,就像其他代码一样).显然,我已经修改了函数"Button_click"的参数以适应新的事件要求,但没有进行其他更改.
我想知道为什么会发生这种情况.EventHandler会变慢吗?或者我做错了什么?还是有最好的做法?
我正在使用VC2010和C#,在Windows窗体应用程序中使用.NET 4.
编辑:
现在我已经"缩小"了我的代码并将其放在那里:
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Button b;
for(n=0;n<100;n++)
{
b = new Button();
b.Location = new System.Drawing.Point(100, 0);
b.Name = "btnGrid";
b.Size = new System.Drawing.Size(50, 50);
b.Text = b.Name;
b.UseVisualStyleBackColor = true;
b.Visible = false;
b.Text = "..";
b.Click += new EventHandler(this.Button_Click);
//b.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Button_ClickUP);
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
Log(elapsedTime, Color.Purple);
Run Code Online (Sandbox Code Playgroud)
Button_Click和Button_Click是:
private void Button_Click(object sender, EventArgs e)
{
}
private void Button_ClickUP(object sender, MouseEventArgs e)
{
}
Run Code Online (Sandbox Code Playgroud)
我将此代码放在一个按钮中,"Log"功能将结果显示在备忘录中.当我启用"Click"时,结果为01.05秒,但是当我启用"MouseUp"时,结果为00.00.
差异 - >第二个!
为什么!?
==编辑==
我使用的是.NET Framework 4. VS2010.赢得XP.我发现了这个:如果我使用.NET 3.5或更低的速度变化:0.5秒.一半.如果我在调试或发布模式下编译它不会改变.
如果我使用可执行文件而没有调试器是快速的.
所以我改变了我的问题:.NET 4比.NET 3慢吗?与独立版本相比,为什么发布模式的工作方式不同?
非常感谢.
代码".Click + = ..."转换为".add_Click(...)"."add_Click"方法可以进行一些逻辑检查.
您可以通过无法重新授权来加快速度:
EventHandler clickHandler = this.Button_Click;
foreach(Button btn in GetButtons()) {
btn.Click += clicHandler;
}
Run Code Online (Sandbox Code Playgroud)
编辑:
你确定,瓶颈是连接处理程序吗?我尝试了for循环(100循环),将eventhandler附加到Click事件,我得到了这个结果:
/* only creation the button and attaching the handler */
button1_Click - A: 0 ms
button1_Click - B: 0 ms
button1_Click - A: 1 ms
button1_Click - B: 0 ms
button1_Click - A: 0 ms
button1_Click - B: 0 ms
/* creation the button, attaching the handler and add to the panel */
button2_Click - A: 223 ms
button2_Click - B: 202 ms
button2_Click - A: 208 ms
button2_Click - B: 201 ms
button2_Click - A: 204 ms
button2_Click - B: 230 ms
Run Code Online (Sandbox Code Playgroud)
源代码:
void button_Click(object sender, EventArgs e) {
// do nothing
}
private void button1_Click(object sender, EventArgs e) {
const int MAX_BUTTONS = 100;
var stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
for (int i = 0; i < MAX_BUTTONS; i++) {
var button = new Button();
button.Click += new EventHandler(button_Click);
}
stopWatch.Stop();
System.Diagnostics.Debug.WriteLine(string.Format("button1_Click - A: {0} ms", stopWatch.ElapsedMilliseconds));
stopWatch.Reset();
stopWatch.Start();
EventHandler clickHandler = this.button_Click;
for (int i = 0; i < MAX_BUTTONS; i++) {
var button = new Button();
button.Click += clickHandler;
}
stopWatch.Stop();
System.Diagnostics.Debug.WriteLine(string.Format("button1_Click - B: {0} ms", stopWatch.ElapsedMilliseconds));
}
private void button2_Click(object sender, EventArgs e) {
const int MAX_BUTTONS = 100;
var stopWatch = new System.Diagnostics.Stopwatch();
this.panel1.Controls.Clear();
stopWatch.Start();
for (int i = 0; i < MAX_BUTTONS; i++) {
var button = new Button();
button.Click += new EventHandler(button_Click);
this.panel1.Controls.Add(button);
}
stopWatch.Stop();
System.Diagnostics.Debug.WriteLine(string.Format("button2_Click - A: {0} ms", stopWatch.ElapsedMilliseconds));
stopWatch.Reset();
this.panel1.Controls.Clear();
stopWatch.Start();
EventHandler clickHandler = this.button_Click;
for (int i = 0; i < MAX_BUTTONS; i++) {
var button = new Button();
button.Click += clickHandler;
this.panel1.Controls.Add(button);
}
stopWatch.Stop();
System.Diagnostics.Debug.WriteLine(string.Format("button2_Click - B: {0} ms", stopWatch.ElapsedMilliseconds));
}
Run Code Online (Sandbox Code Playgroud)
编辑2: 我尝试比较附加Click处理程序与附加MouseUp处理程序所花费的时间.看来,附加的MouseUp事件比Click事件更快.
我认为问题将出在其他地方.在循环期间不收集GC吗?或者你不在那里做点什么吗?
结果:
button1_Click - Click_A: 6 ms
button1_Click - Click_B: 6 ms
button1_Click - MouseUp_A: 15 ms
button1_Click - MousUp_B: 7 ms
button1_Click - Click_A: 16 ms
button1_Click - Click_B: 7 ms
button1_Click - MouseUp_A: 16 ms
button1_Click - MousUp_B: 10 ms
button1_Click - Click_A: 14 ms
button1_Click - Click_B: 19 ms
button1_Click - MouseUp_A: 27 ms
button1_Click - MousUp_B: 5 ms
button1_Click - Click_A: 17 ms
button1_Click - Click_B: 17 ms
button1_Click - MouseUp_A: 24 ms
button1_Click - MousUp_B: 8 ms
button1_Click - Click_A: 6 ms
button1_Click - Click_B: 5 ms
button1_Click - MouseUp_A: 14 ms
button1_Click - MousUp_B: 7 ms
button1_Click - Click_A: 14 ms
button1_Click - Click_B: 9 ms
button1_Click - MouseUp_A: 15 ms
button1_Click - MousUp_B: 7 ms
Run Code Online (Sandbox Code Playgroud)
码:
private void button1_Click(object sender, EventArgs e) {
const int MAX_BUTTONS = 1000;
var stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
for (int i = 0; i < MAX_BUTTONS; i++) {
var button = new Button();
button.Click += new EventHandler(button_Click);
}
stopWatch.Stop();
System.Diagnostics.Debug.WriteLine(string.Format("button1_Click - Click_A: {0} ms", stopWatch.ElapsedMilliseconds));
stopWatch.Reset();
stopWatch.Start();
EventHandler clickHandler = this.button_Click;
for (int i = 0; i < MAX_BUTTONS; i++) {
var button = new Button();
button.Click += clickHandler;
}
stopWatch.Stop();
System.Diagnostics.Debug.WriteLine(string.Format("button1_Click - Click_B: {0} ms", stopWatch.ElapsedMilliseconds));
stopWatch.Start();
for (int i = 0; i < MAX_BUTTONS; i++) {
var button = new Button();
button.MouseUp += new MouseEventHandler(button_MouseUp);
}
stopWatch.Stop();
System.Diagnostics.Debug.WriteLine(string.Format("button1_Click - MouseUp_A: {0} ms", stopWatch.ElapsedMilliseconds));
stopWatch.Reset();
stopWatch.Start();
MouseEventHandler mouseUpHandler = this.button_MouseUp;
for (int i = 0; i < MAX_BUTTONS; i++) {
var button = new Button();
button.MouseUp += mouseUpHandler;
}
stopWatch.Stop();
System.Diagnostics.Debug.WriteLine(string.Format("button1_Click - MousUp_B: {0} ms", stopWatch.ElapsedMilliseconds));
}
Run Code Online (Sandbox Code Playgroud)
编辑:add_Click方法
的主体(= Click += ...)很粗糙:
public void add_Click(EventHandler value) {
this.Events.AddHandler(ClickEventIdentifier, value);
}
Run Code Online (Sandbox Code Playgroud)
MouseUp事件看起来很相似.至少两个事件都使用Events属性来保存事件的委托列表.
但是,如果我尝试了几件事,我就无法解决事件的问题:(..你可以在另一台计算机上重现相同的行为吗?
| 归档时间: |
|
| 查看次数: |
9473 次 |
| 最近记录: |