我不太了解调用。我知道它所做的是它告诉当前操作要在它需要运行的线程上运行(UI线程)。但我没有得到的是为什么你可以做这么多不同的版本。例如:
this.BeginInvoke(new MethodInvoker(delegate { currping.Text = Status; }));
this.BeginInvoke(new Action(() => { currping.Text = Status; }));
我不明白是否存在差异。他们都会从我能掌握的东西中做同样的事情。
我在这里错过了什么吗?
答案 0 :(得分:3)
Action
在.NET 3.5框架中添加为一般委托,不带任何参数并且不返回任何内容,而MethodInvoker
自1.1以来就已存在,因此您通常只会看到使用{的旧代码{1}}。两个委托类型具有相同的签名。
MethodInvoker
实际上需要一个BeginInvoke()
对象,因此任何不带参数的委托都可以与该重载一起使用。 (对于需要参数的委托,有一个Delegate
重载,但我倾向于使用无参数闭包。)
因为(Delegate, object[])
是一般类型,所以必须以某种方式指定您提供的委托类型,因为编译器无法推断它(见下文)。这比Delegate
替代方案短,但只有几个字符,而且实际上并没有更多或更不清楚:
new Action
您必须在此处指定委托类型,因为编译器不知道您想要哪种委托类型。例如:
this.BeginInvoke((Action)(() => { ... }));
这是有效的,因为编译器可以根据Action foo = () => { };
的类型推断出委托类型应该是foo
。
Action
这些是编译时错误,因为有许多委托类型匹配签名“不带参数并返回// All of these examples cause CS1660.
Delegate foo1 = () => { };
object foo2 = () => { };
var foo3 = () => { };
”,编译器不会假装知道你想要的。 (在void
和object
个案例中,您可能还有一个var
对象,它根本不是代理。但是,如果你有同样的错误,你会得到同样的错误使用Expression<>
而不是lambda表达式。)
答案 1 :(得分:1)
new Something(
部分和最内部括号内的部分分为两部分。
MethodInvoker
和Action
都是Delegates,您需要将它们视为“函数模式”定义。这两个“模式”所代表的是“一个不接受任何参数并返回void的函数”
namespace System.Windows.Forms
{
public delegate void MethodInvoker();
}
namespace System
{
public delegate void Action()
}
因此它们都代表完全相同的“模式”,它只是在两个地方定义,以方便编码。例如,更明显的是,您计划使用委托来使用MethodInvoker
来调用Winforms表单的方法,而不是使用Action
。
第二部分是括号内的东西。这两个定义都意味着相同的事情,但模式() => { ... }
是Lambada Expression并且直到visual studio 2008或更新版本才被添加。它们都意味着“我在这里定义一个内联函数”,这会创建一个所谓的Anonymous Function,因为它是一个没有名称的函数。您也可以在
public void Foo()
{
this.BeginInvoke(new Action(Bar)); //BeginInvoke will call the function Bar()
}
private void Bar()
{
}