线程基础二 向线程传递参数
在C#中,向线程中传递参数的方法通常有三种,将在下面的例子中展示。
static void Main(string[] args) { var sample = new ThreadSample(10); //1 自定义类 var threadOne = new Thread(sample.CountNumber); threadOne.Name = "ThreadOne"; threadOne.Start(); threadOne.Join(); Console.WriteLine("-------------------"); //2 object只能传单个参数 var threadTwo = new Thread(Count); threadTwo.Name = "ThreadTwo"; threadTwo.Start(8); threadTwo.Join(); Console.WriteLine("-------------------"); //3 Lambda表达式传递 var threadThree = new Thread(()=>CountNumbers(12)); threadThree.Name = "ThreadThree"; threadThree.Start(); threadThree.Join(); Console.WriteLine("-------------------"); int i = 10; var threadFour = new Thread(()=>PrintNumber(i)); i = 20; var threadFive = new Thread(()=>PrintNumber(i)); threadFour.Start();//20 threadFive.Start();//20 } static void Count(Object iterations) { CountNumbers((int)iterations); } static void CountNumbers(int iterations) { for (int i = 0; i < iterations; i++) { System.Threading.Thread.Sleep(TimeSpan.FromSeconds(0.5)); Console.WriteLine($"{System.Threading.Thread.CurrentThread.Name} prints {i}"); } } static void PrintNumber(int number) { Console.WriteLine(number); }
public class ThreadSample { private readonly int _iterations; public ThreadSample(int iterations) { _iterations = iterations; } public void CountNumber() { for (int i = 0; i < _iterations; i++) { System.Threading.Thread.Sleep(TimeSpan.FromSeconds(0.5)); Console.WriteLine($"{System.Threading.Thread.CurrentThread.Name} prints {i}"); } } }
1、当主程序启动时,首先创建了ThreadSample的一个对象,并提供了一个迭代次数。然后使用该对象的CountNumbers方法启动线程。该方法运行在另一个线程中,但是使用数字是10,该数字是通过ThreadSample对象的构造函数传入的。因此我们只是使用相同的间接方式将迭代次数传递给另一个线程。
2、另一种传递的方式是使用Thread.Start()方法。该方法会接收到一个对象,并将该对象传递给线程。为了应用该方法,在线程中启动的方法必须接受object类型的单个参数。在创建ThreadTwo时演示了该方式。将8作为一个对象传给了Count方法,然后Count方法被转为Int型。
3、接下来的方式是Lambda表达式。Lambda表达式定义了一个不属于任何类的方法。我们创建了一个方法,该方法使用需要的参数调用了另一个方法,并在另一个线程中运行该方法。使用Lambda表达式引用另一个C#对象的方式被称呼为闭包。当在Lambda表达式中使用任何局部变量时,C#会生成一个类,并将该变量作为类的一个属性。所以实际上该方式与threadOne中使用的是一样的,但是我们无需定义类,C#编译器会自动帮我们实现。但这可能导致几个问题。例如,如果在多个lambda表达式中使用相同变量,它们会共享该资源。在上面的例子中可以看到threadFour以及threadFive线程它们都会打印20,因为在这两个线程启动之前变量被修改为20.