MethodInvoker vs Action for Control.BeginInvoke

后端 未结 7 939
走了就别回头了
走了就别回头了 2020-11-28 22:33

Which is more correct and why?

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

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


        
7条回答
  •  难免孤独
    2020-11-28 23:00

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

提交回复
热议问题