哪个更正确,为什么?
Control.BeginInvoke(new Action(DoSomething), null);
private void DoSomething()
{
MessageBox.Show("What a great post");
}
要么
Control.BeginInvoke((MethodInvoker) delegate {
MessageBox.Show("What a great post");
});
我有点觉得我做同样的事情,因此当使用正确时MethodInvoker
VS Action
,甚至写一个lambda表达式?
编辑:我知道,是不是真的多写一个lambda VS之间的差异的Action
,但MethodInvoker
似乎为特定目的而作出。 难道是做什么不同?
两者都同样正确的,但对于文档Control.Invoke
指出:
委托可以是事件处理程序的一个实例,在这种情况下发送者参数将包含这样的控制,和事件参数将包含EventArgs.Empty。 该代表还可以MethodInvoker的一个实例,或任何其他代表,需要一个空的参数列表。 到事件处理程序或MethodInvoker代表的呼叫将比另一个类型的委托的呼叫更快。
所以MethodInvoker
将是一个更有效的选择。
对于每个溶液波纹管我运行131072(128×1024)的迭代(在一个独立的线程)。 Visual Studio 2010的性能助手给这个结果:
- 只读MethodInvoker:5664.53(+ 0%)
- 新MethodInvoker:5828.31(+ 2.89%)
- 功能铸在MethodInvoker:5857.07(+ 3.40%)
- 只读操作:6467.33(+ 14.17%)
- 新动作:6829.07(+ 20.56%)
调用一个新的动作在每次迭代
private void SetVisibleByNewAction()
{
if (InvokeRequired)
{
Invoke(new Action(SetVisibleByNewAction));
}
else
{
Visible = true;
}
}
调用一个只读,建立构造, 行动在每次迭代
// private readonly Action _actionSetVisibleByAction
// _actionSetVisibleByAction= SetVisibleByAction;
private void SetVisibleByAction()
{
if (InvokeRequired)
{
Invoke(_actionSetVisibleByAction);
}
else
{
Visible = true;
}
}
呼吁在每次迭代新MethodInvoker。
private void SetVisibleByNewMethodInvoker()
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(SetVisibleByNewMethodInvoker));
}
else
{
Visible = true;
}
}
调用一个只读,建立构造,MethodInvoker在每次迭代
// private readonly MethodInvoker _methodInvokerSetVisibleByMethodInvoker
// _methodInvokerSetVisibleByMethodInvoker = SetVisibleByMethodInvoker;
private void SetVisibleByMethodInvoker()
{
if (InvokeRequired)
{
Invoke(_methodInvokerSetVisibleByMethodInvoker);
}
else
{
Visible = true;
}
}
呼吁在每个迭代投在MethodInvoker功能
private void SetVisibleByDelegate()
{
if (InvokeRequired)
{
Invoke((MethodInvoker) SetVisibleByDelegate);
}
else
{
Visible = true;
}
}
呼吁“新行动”的解决方案的实例:
private void ButtonNewActionOnClick(object sender, EventArgs e)
{
new Thread(TestNewAction).Start();
}
private void TestNewAction()
{
var watch = Stopwatch.StartNew();
for (var i = 0; i < COUNT; i++)
{
SetVisibleByNewAction();
}
watch.Stop();
Append("New Action: " + watch.ElapsedMilliseconds + "ms");
}
我更喜欢使用lambda表达式和动作/ funcs中:
Control.BeginInvoke(new Action(() => MessageBox.Show("What a great post")));
行动在系统中定义的,而MethodInvoker在System.Windows.Forms的定义 - 您可以使用动作会更好,因为它是可移植到其他地方。 你还会发现更多的地方接受作为行动比MethodInvoker参数。
然而,该文件确实表明,调用类型的事件处理程序或MethodInvoker在Control.Invoke()的代表将超过任何其他类型的更快。
除了这namepsace他们在,我不相信有行动和MethodInvoker之间有意义的功能上的区别-它们基本上都定义为:
public delegate void NoParamMethod();
顺便说一句,动作有几个重载,允许参数以传递 - 这是通用的,因此,他们可以是类型安全的。
同时每MSDN:
MethodInvoker提供了用于调用与空隙参数列表的方法的简单的委托。 这代表可以拨打电话到控件的调用方法时,你需要一个简单的委托,但不希望自己定义一个使用,或。
在另一方面,一个动作可能需要长达4个参数。
但我不认为这是MethodInvoker和行动之间有什么区别,因为它们都只是封装的委托,不采取paremter并返回void
如果你看看他们的定义,你会简单地看到这一点。
public delegate void MethodInvoker();
public delegate void Action();
顺便说一句,你也可以写你的第二个行。
Control.BeginInvoke(new MethodInvoker(DoSomething), null);
这是优先考虑在大多数情况下的事,除非你打算重用DoSomething的()方法。 另外,匿名函数将放置在堆的范围变量,可能使一个更昂贵的功能。
不要忘记以某种方式检查是否控制可在瞬间,以避免在封闭形式的错误。
if(control.IsHandleCreated)
control.BeginInvoke((MethodInvoker)(() => control.Text="check123"));