如何“;将任意数量的参数传递给方法“”;通过lambda表达式的线程的
本文关键字:通过 表达式 线程 方法 lambda 参数传递 任意数 如何 | 更新日期: 2023-09-27 18:00:38
我遵循Joseph Albahari的《C#中的线程》的"PART 1:GETTING STARTED"中的"将数据传递到线程"。
即通道:
====报价开始
"使用这种方法,您可以将任意数量的参数传递给方法。您甚至可以将整个实现封装在多语句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)'
如何消除代码的歧义以便运行它已回答(遗漏括号。无论如何,这不是最初的主要问题)- 此外,我不太清楚空列表
() =>
指向/应用于哪里 - 还有,"可以向方法传递任意数量的参数"的方法是什么
- 如何理解(任意数量的)参数通过空列表的传递
更新(针对Jon Skeet的评论):
不,我没有拘泥于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();
另一个取CCD_ 7,定义为:
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表达式的开头。()
表示此表达式不接受任何参数。