1

我遵循将数据传递给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)”

  1. 您如何消除代码的歧义以便运行它? 已回答(遗漏了括号。无论如何,这不是最初的主要问题)
  2. 另外,我不太了解空列表 () =>指向/应用到哪里?
  3. 那么,“您可以将任意数量的参数传递给该方法”的方法是什么?
  4. 如何理解通过空列表传递(任意数量)参数?

更新(针对 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,尽管我将另一个答案标记为正确的答案是为了立即回答我什至最初没有问过的问题-如何将某些内容放在空括号中(我已经害怕通过列表来称呼它或通过参数)

4

4 回答 4

3

您需要明确参数列表:

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();

另一个采用 aParameterizedThreadStart定义为:

delegate void ParameterizedThreadStart(object state);

由于您省略了参数列表,编译器不知道您使用的是哪种委托类型。

我假设“任意数量的参数”是由您的代表封闭的变量。例如,您可以:

string message = "This is so easy!";
var thread = new Thread(delegate() {
    Console.WriteLine(message);
});
thread.Start();

您可以使用 aParameterizedThreadStart将任意对象传递给您的线程委托,例如

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);
于 2013-02-22T12:47:33.697 回答
2

您需要后面的括号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方法中,或者创建一个可以保存数据的类,将线程代码放在类中,并为每个线程创建一个实例开始。

于 2013-02-22T12:56:00.603 回答
1

为了解决模棱两可的调用,您可以添加空括号(委托将被视为 ThreadStart 委托):

new Thread(delegate() {
    Console.WriteLine("I'm running on another thread!");
    Console.WriteLine("This is so easy!");
}).Start();

或者添加 state 参数(delegate 将被视为 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();
于 2013-02-22T12:46:45.747 回答
1

() =>不是 C# 中的空列表。在本书中使用的上下文中,它是 lambda 表达式的开始。这()意味着这个表达式不带参数。

于 2013-02-22T12:50:51.557 回答