Dispatcher.Invoke和lambda语法 - 新行动
问题描述:
什么是VSDispatcher.Invoke和lambda语法 - 新行动
Application.Current.Dispatcher.Invoke(
() =>
{
txtRowCount.Text = string.Format("{0}", rowCount);
}
); //end-Invoke
Application.Current.Dispatcher.Invoke(
new Action(() =>
{
txtRowCount.Text = string.Format("{0}", rowCount);
})
); //end-Invoke
之间的差异。如果编译器抱怨,我会用其他的,但我不知道到底发生了什么上。
答
它很可能取决于您正在调用和传递委托的方法。例如,对于这样的签名的方法可以使用Lambda隐含创建Action
:
void RunAction(Action thing) {}
虽然这样的方法就无法弄清楚你想要什么类型的委托:
void RunDelegate(Delegate thing) {}
原因是Delegate
类型是可代表任何delegate
表达式的基类。例如,您可以将第二个函数Action
,Func<T>
,Predicate<T>
,EventHandler
或您可以想到的任何其他委托(包括自定义委托)传递给第二个函数。在这种情况下,编译器/运行时不知道要将自定义委托转换为什么。函数的责任是弄清楚如何调用委托或抛出异常(如果它不理解)。
在另一方面,Action
是没有参数和不返回值的方法的具体代表:
delegate void Action();
所以,当一个方法有一个类型为Action
参数,那么任何拉姆达签名符合该代表可以隐式转换为您。
对于Dispatcher.BeginInvoke
方法,这需要一个Delegate
,你可以通过它是取0参数(这是好的,如果它返回的东西,但我怀疑的返回值被用于任何东西)的任何代表。所以,你可以通过它像Action
或Func<T>
。如果你传递一个委托,它需要传递给它的参数,它仍然会编译,但是当Dispatcher尝试调用这个方法时会在运行时抛出一个异常。
为了演示,我做了一个快速的小控制台应用程序。
static int Main(string[] args)
{
// These work
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => Console.WriteLine("Action")));
Dispatcher.CurrentDispatcher.BeginInvoke(new Func<int>(() => { Console.WriteLine("Func<int>"); return 42; }));
// This one throws a TargetParameterCountException when the dispatcher gets to it
//Dispatcher.CurrentDispatcher.BeginInvoke(new Action<bool>(b => Console.WriteLine("Action<bool>")));
// Queue a dispatcher shutdown at the end and run the dispatcher
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => Dispatcher.CurrentDispatcher.InvokeShutdown()));
Dispatcher.Run();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
return 0;
}
它们是相同的。第二个片段中的lambda被隐式转换为一个Action。虽然通常是相同的,但我也推荐使用TextBlock的Dispatcher,比如'txtRowCount.Dispatcher.Invoke(()=> txtRowCount.Text = string.Format(“{0}”,rowCount));' – Clemens
https:/ /stackoverflow.com/questions/765966/what-is-the-difference-between-new-action-and-a-lambda – mm8