线程基础二 向线程传递参数

  在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.

posted @ 2018-12-17 23:50  我是搞艺术的  阅读(247)  评论(0编辑  收藏  举报