MethodInvoker vs Action for Control.BeginInvoke

哪个更正确,为什么?

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与Action之间并没有什么区别,但MethodInvoker似乎是为特定目的而制作的。 它做了什么不同吗?


两者同样正确,但Control.Invoke的文档声明:

委托可以是EventHandler的一个实例,在这种情况下,sender参数将包含此控件,而event参数将包含EventArgs.Empty。 该委托也可以是MethodInvoker的实例,或任何其他采用void参数列表的委托。 对EventHandler或MethodInvoker委托的调用比对另一种委托类型的调用要快。

所以MethodInvoker会是一个更有效的选择。


对于每个解决方案,我运行131072(128 * 1024)迭代(在一个单独的线程中)。 VS2010性能助手给出了这样的结果:

  • 只读MethodInvoker:5664.53(+ 0%)
  • New MethodInvoker:5828.31(+ 2.89%)
  • 函数在MethodInvoker中投射:5857.07(+ 3.40%)
  • 只读操作:6467.33(+ 14.17%)
  • 新行动:6829.07(+ 20.56%)
  • 在每次迭代时调用一个新的Action

        private void SetVisibleByNewAction()
        {
            if (InvokeRequired)
            {
                Invoke(new Action(SetVisibleByNewAction));
            }
            else
            {
                Visible = true;
            }
        }
    

    在每次迭代时调用一个只读构造函数, Action

        // 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");
        }
    

    我更喜欢使用lambdas和Actions / Funcs:

    Control.BeginInvoke(new Action(() => MessageBox.Show("What a great post")));
    
    链接地址: http://www.djcxy.com/p/50111.html

    上一篇: MethodInvoker vs Action for Control.BeginInvoke

    下一篇: define an enum than can be dot called like ENUMTYPE.ENUMVAL