MethodInvoker与Control.BeginInvoke的Action

Mik*_*e_G 56 .net c# delegates invoke

哪个更正确,为什么?

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

private void DoSomething()
{
    MessageBox.Show("What a great post");
}
Run Code Online (Sandbox Code Playgroud)

要么

Control.BeginInvoke((MethodInvoker) delegate { 
    MessageBox.Show("What a great post");
}); 
Run Code Online (Sandbox Code Playgroud)

我觉得我在做同样的事情,所以什么时候适合使用MethodInvokervs Action,甚至写一个lambda表达式?

编辑:我知道写一个lambda vs之间并没有什么区别Action,但MethodInvoker似乎是出于特定目的.它有什么不同吗?

Jon*_*eet 76

两者都是同样正确的,但Control.Invoke状态文件:

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

MethodInvoker将是一个更有效的选择.

  • 简单地说:它听起来像检查(作为特殊情况)这两个使用is/as检查,并使用Invoke而不是DynamicInvoke - 这显着**更快 (29认同)

Ora*_*ace 26

对于每个解决方案,我运行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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

    // private readonly Action _actionSetVisibleByAction
    // _actionSetVisibleByAction= SetVisibleByAction;
    private void SetVisibleByAction()
    {
        if (InvokeRequired)
        {
            Invoke(_actionSetVisibleByAction);
        }
        else
        {
            Visible = true;
        }
    }
Run Code Online (Sandbox Code Playgroud)

在每次迭代时调用一个新的MethodInvoker.

    private void SetVisibleByNewMethodInvoker()
    {
        if (InvokeRequired)
        {
            Invoke(new MethodInvoker(SetVisibleByNewMethodInvoker));
        }
        else
        {
            Visible = true;
        }
    }
Run Code Online (Sandbox Code Playgroud)

在每次迭代时调用只读,构建构造函数MethodInvoker

    // private readonly MethodInvoker _methodInvokerSetVisibleByMethodInvoker 
    // _methodInvokerSetVisibleByMethodInvoker = SetVisibleByMethodInvoker;
    private void SetVisibleByMethodInvoker()
    {
        if (InvokeRequired)
        {
            Invoke(_methodInvokerSetVisibleByMethodInvoker);
        }
        else
        {
            Visible = true;
        }
    }
Run Code Online (Sandbox Code Playgroud)

在每次迭代时调用MethodInvoker中的函数

    private void SetVisibleByDelegate()
    {
        if (InvokeRequired)
        {
            Invoke((MethodInvoker) SetVisibleByDelegate);
        }
        else
        {
            Visible = true;
        }
    }
Run Code Online (Sandbox Code Playgroud)

调用"新动作"解决方案的示例:

    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");
    }
Run Code Online (Sandbox Code Playgroud)


小智 10

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

Control.BeginInvoke(new Action(() => MessageBox.Show("What a great post")));
Run Code Online (Sandbox Code Playgroud)


LBu*_*kin 5

Action是在System中定义的,而MethodInvoker是在System.Windows.Forms中定义的-使用Action可能会更好,因为它可以移植到其他地方。与MethodInvoker相比,您还会发现更多接受Action作为参数的位置。

但是,文档确实指出,对Control.Invoke()中EventHandler或MethodInvoker类型的委托的调用将比任何其他类型都快。

除了它们所在的名称空间之外,我不认为Action和MethodInvoker之间存在有意义的功能差异-它们本质上都定义为:

public delegate void NoParamMethod();
Run Code Online (Sandbox Code Playgroud)

顺便说一句,Action具有多个重载,它们允许传入参数-并且它是通用的,因此它们可以是类型安全的。