![](/img/trans.png)
[英]How to pass a lambda expression to a method expecting lambda expression?
[英]How to “pass in any number of arguments to the method” of a thread through lambda expression?
我遵循约瑟夫·阿尔巴哈里(Joseph Albahari)将数据传递到线程 “ C#中的线程 ”的“部分1:入门”的线程中。
即段落:
======报价开始
“ 通过这种方法,您可以将任意数量的参数传递(到哪里?) 。您甚至可以将整个实现包装在多语句lambda中:
new Thread (() =>
{
Console.WriteLine ("I'm running on another thread!");
Console.WriteLine ("This is so easy!");
}).Start();*
您可以使用匿名方法在C#2.0中几乎一样轻松地完成相同的操作:
new Thread (delegate()
{
...
}).Start();
============报价结束
也就是说,我尝试将“轻松”作为:
new Thread (delegate { Console.WriteLine("I'm running on another thread!"); Console.WriteLine("This is so easy!"); } ).Start();
但是会产生错误:
下列方法或属性之间的调用不明确:'System.Threading.Thread.Thread(System.Threading.ThreadStart)'和'System.Threading.Thread.Thread(System.Threading.ParameterizedThreadStart)'
() =>
指向/应用于何处? 更新 (解决乔恩·斯基特的评论):
不,我不喜欢C#2。
与上一段相同的问题:
==========报价开始:
“ 将参数传递给线程的目标方法的最简单方法是执行一个lambda表达式,该表达式使用所需的参数调用该方法:
static void Main() { Thread t = new Thread ( () => Print ("Hello from t!") ); t.Start(); } static void Print (string message) { Console.WriteLine (message); }
通过这种方法,您可以将任意数量的参数传递给该方法。”
==============报价结束
更新2:
最完整的答案是@Lee的IMO,尽管我标记为正确的另一个答案是想立即回答我什至没有问到的问题-如何将某些内容放在空括号中(我已经很害怕按列表或按名称参数)
您需要使参数列表明确:
new Thread
(delegate()
{
Console.WriteLine("I'm running on another thread!");
Console.WriteLine("This is so easy!");
}
).Start();
delegate
关键字允许您定义匿名方法 。 Lambda表达式(即,使用() => { ... }
语法)相似,但是使用delegate
可以省略参数列表。 在这种情况下,这是不明确的,因为Thread
有两个构造函数采用不同的委托类型。 一个采用ThreadStart
,其定义为
delegate void ThreadStart();
另一个采用ParameterizedThreadStart
,其定义为:
delegate void ParameterizedThreadStart(object state);
由于省略了参数列表,因此编译器不知道您使用的是哪种委托类型。
我假设“任意数量的参数”是由您的代表封闭的变量。 例如,您可能有:
string message = "This is so easy!";
var thread = new Thread(delegate() {
Console.WriteLine(message);
});
thread.Start();
您可以使用ParameterizedThreadStart
将任意对象传递给线程委托,例如
public class ThreadData {
//properties to pass to thread
}
ThreadData data = new ThreadData { ... }
Thread thread = new Thread((object state) => {
ThreadData data = (ThreadData)state;
});
thread.Start(data);
您需要在delegate
后的括号中指定参数,在这种情况下,无需参数:
new Thread(
delegate() {
Console.WriteLine("I'm running on another thread!");
Console.WriteLine("This is so easy!");
}
).Start();
作者在谈论的“任意数量的参数”是,您可以使用在单独的线程中运行的代码内创建委托的范围内的数据,而不必将数据传递给Start
方法:
string msg1 = "I'm running on another thread!";
string msg2 = "This is so easy!";
new Thread(
delegate() {
Console.WriteLine(msg1);
Console.WriteLine(msg2);
}
).Start();
实际情况是变量不再是方法中的局部变量,而是自动存储在闭包中,委托与定义该方法的方法共享该闭包。
只要您只想启动一个线程,此方法就可以很好地工作。 如果要启动使用不同数据的多个线程,则可以将数据传递到Start
方法中,或者创建一个可以保存数据的类,将该线程的代码放入该类中,并为每个线程创建一个实例。你先来。
为了解决歧义调用,您可以添加空括号(该委托将被视为ThreadStart委托):
new Thread(delegate() {
Console.WriteLine("I'm running on another thread!");
Console.WriteLine("This is so easy!");
}).Start();
或添加状态参数(代理将被视为ParametrizedThreadStart)。它可以工作,但是很奇怪,因为您不需要该参数。
new Thread(delegate(object state) {
Console.WriteLine("I'm running on another thread!");
Console.WriteLine("This is so easy!");
}).Start();
或将委托转换为ThreadStart
new Thread((ThreadStart)delegate {
Console.WriteLine("I'm running on another thread!");
Console.WriteLine("This is so easy!");
}).Start();
() =>
在C#中不是一个空列表。 在上下文中,它是lambda表达式的开始。 ()
表示此表达式不带参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.