MethodInvoker,相较于Control.BeginInvoke行动(MethodInvok

2019-06-17 13:20发布

哪个更正确,为什么?

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似乎为特定目的而作出。 难道是做什么不同?

Answer 1:

两者都同样正确的,但对于文档Control.Invoke指出:

委托可以是事件处理程序的一个实例,在这种情况下发送者参数将包含这样的控制,和事件参数将包含EventArgs.Empty。 该代表还可以MethodInvoker的一个实例,或任何其他代表,需要一个空的参数列表。 到事件处理程序或MethodInvoker代表的呼叫将比另一个类型的委托的呼叫更快。

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



Answer 2:

对于每个溶液波纹管我运行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");
    }


Answer 3:

我更喜欢使用lambda表达式和动作/ funcs中:

Control.BeginInvoke(new Action(() => MessageBox.Show("What a great post")));


Answer 4:

行动在系统中定义的,而MethodInvoker在System.Windows.Forms的定义 - 您可以使用动作会更好,因为它是可移植到其他地方。 你还会发现更多的地方接受作为行动比MethodInvoker参数。

然而,该文件确实表明,调用类型的事件处理程序或MethodInvoker在Control.Invoke()的代表将超过任何其他类型的更快。

除了这namepsace他们在,我不相信有行动和MethodInvoker之间有意义的功能上的区别-它们基本上都定义为:

public delegate void NoParamMethod();

顺便说一句,动作有几个重载,允许参数以传递 - 这是通用的,因此,他们可以是类型安全的。



Answer 5:

同时每MSDN:

MethodInvoker提供了用于调用与空隙参数列表的方法的简单的委托。 这代表可以拨打电话到控件的调用方法时,你需要一个简单的委托,但不希望自己定义一个使用,或。

在另一方面,一个动作可能需要长达4个参数。

但我不认为这是MethodInvoker行动之间有什么区别,因为它们都只是封装的委托,不采取paremter并返回void

如果你看看他们的定义,你会简单地看到这一点。

public delegate void MethodInvoker();
public delegate void Action();

顺便说一句,你也可以写你的第二个行。

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


Answer 6:

这是优先考虑在大多数情况下的事,除非你打算重用DoSomething的()方法。 另外,匿名函数将放置在堆的范围变量,可能使一个更昂贵的功能。



Answer 7:

不要忘记以某种方式检查是否控制可在瞬间,以避免在封闭形式的错误。

if(control.IsHandleCreated)
control.BeginInvoke((MethodInvoker)(() => control.Text="check123"));


文章来源: MethodInvoker vs Action for Control.BeginInvoke