代码“.Click += ...”被转换为“.add_Click( ... )”。 “add_Click”方法可以进行一些逻辑检查。
您可以在不重新创建委托的情况下稍微加快速度:
EventHandler clickHandler = this.Button_Click;
foreach(Button btn in GetButtons()) {
btn.Click += clicHandler;
}
EDIT:
您确定瓶颈是附加处理程序吗?
我尝试使用 for 循环(100 次循环)将事件处理程序附加到 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
源代码:
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));
}
EDIT 2:我尝试比较附加 Click 处理程序与附加 MouseUp 处理程序所花费的时间。似乎并非如此,附加的 MouseUp 事件比 Click 事件更快。
我认为问题会出在其他地方。 GC在循环期间不收集吗?或者你不在那里做其他事情吗?
Results:
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
Code:
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));
}
EDIT :的身体add_Click
方法(=Click += ...
)是粗糙的:
public void add_Click(EventHandler value) {
this.Events.AddHandler(ClickEventIdentifier, value);
}
MouseUp 事件看起来类似。至少两个事件都使用Events
用于保存事件代表列表的属性。
但是,如果我尝试了几件事,我就无法得到您所写的事件的问题:(。
您可以在另一台计算机上重现相同的行为吗?