MethodInvoker vs Action for Control.BeginInvoke

Which is more correct and why?

Control.BeginInvoke(new Action(DoSomething), null);

private void DoSomething()
{
    MessageBox.Show("What a great post");
}

or

Control.BeginInvoke((MethodInvoker) delegate { 
    MessageBox.Show("What a great post");
}); 

I kinda feel like I am doing the same thing, so when is the right time to use MethodInvoker vs Action , or even writing a lambda expression?

EDIT: I know that there isn't really much of a difference between writing a lambda vs Action , but MethodInvoker seems to be made for a specific purpose. Is it doing anything different?


Both are equally correct, but the documentation for Control.Invoke states that:

The delegate can be an instance of EventHandler, in which case the sender parameter will contain this control, and the event parameter will contain EventArgs.Empty. The delegate can also be an instance of MethodInvoker, or any other delegate that takes a void parameter list. A call to an EventHandler or MethodInvoker delegate will be faster than a call to another type of delegate.

So MethodInvoker would be a more efficient choice.


For each solution bellow I run a 131072 (128*1024) iterations (in one separated thread). The VS2010 performance assistant give this results:

  • read-only MethodInvoker: 5664.53 (+0%)
  • New MethodInvoker: 5828.31 (+2.89%)
  • function cast in MethodInvoker: 5857.07 (+3.40%)
  • read-only Action: 6467.33 (+14.17%)
  • New Action: 6829.07 (+20.56%)
  • Call to a new Action at each iteration

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

    Call to a read-only, build in constructor, Action at each iteration

        // private readonly Action _actionSetVisibleByAction
        // _actionSetVisibleByAction= SetVisibleByAction;
        private void SetVisibleByAction()
        {
            if (InvokeRequired)
            {
                Invoke(_actionSetVisibleByAction);
            }
            else
            {
                Visible = true;
            }
        }
    

    Call to a new MethodInvoker at each iteration.

        private void SetVisibleByNewMethodInvoker()
        {
            if (InvokeRequired)
            {
                Invoke(new MethodInvoker(SetVisibleByNewMethodInvoker));
            }
            else
            {
                Visible = true;
            }
        }
    

    Call to a read-only, build in constructor, MethodInvoker at each iteration

        // private readonly MethodInvoker _methodInvokerSetVisibleByMethodInvoker 
        // _methodInvokerSetVisibleByMethodInvoker = SetVisibleByMethodInvoker;
        private void SetVisibleByMethodInvoker()
        {
            if (InvokeRequired)
            {
                Invoke(_methodInvokerSetVisibleByMethodInvoker);
            }
            else
            {
                Visible = true;
            }
        }
    

    Call to the function cast in MethodInvoker at each iteration

        private void SetVisibleByDelegate()
        {
            if (InvokeRequired)
            {
                Invoke((MethodInvoker) SetVisibleByDelegate);
            }
            else
            {
                Visible = true;
            }
        }
    

    Example of call for the "New Action" solution :

        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/50112.html

    上一篇: 你能用一个好的C#示例来解释Liskov替换原理吗?

    下一篇: MethodInvoker vs Action for Control.BeginInvoke