多線程之向線程傳遞參數


 

總體來說多線程中向線程傳遞參數有3種方式

  1. 創建對象,初始化對象中的一些值,然后在Start()方法中調用該對象方法
  2. 通過lambda表達式
  3. Thread.Start方法

先看代碼:

 

     static void Count(object iterations)
        {
            CountNumbers((int)iterations);
        }

        static void CountNumbers(int iterations)
        {
            for (int i = 1; i <= iterations; i++)
            {
                Thread.Sleep(TimeSpan.FromSeconds(0.5));
                Console.WriteLine("{0} prints {1}", Thread.CurrentThread.Name, i);
            }
        }

        static void PrintNumber(int number)
        {
            Console.WriteLine(number);
        }

        class ThreadSample
        {
            private readonly int _iterations;

            public ThreadSample(int iterations)
            {
                _iterations = iterations;
            }
            public void CountNumbers()
            {
                for (int i = 1; i <= _iterations; i++)
                {
                    Thread.Sleep(TimeSpan.FromSeconds(0.5));
                    Console.WriteLine("{0} prints {1}", Thread.CurrentThread.Name, i);
                }
            }
        }

 

 

        static void Main(string[] args)
        {
       //首先創建了ThreadSample類的一個對象,並提供了一個迭代次數
var sample = new ThreadSample(10);

       (1)第一種方式.自定義類的方式        //使用ThreadSample對象的CountNumbers方法啟動線程
       //該方法運行在另一個線程中,但是使用數字10,該數字是通過ThreadSample對象的構造函數傳入的
var threadOne = new Thread(sample.CountNumbers);(我們只是使用相同的間接方式將該迭代次數傳遞給另一個線程) threadOne.Name = "ThreadOne"; threadOne.Start(); threadOne.Join(); Console.WriteLine("--------------------------");       
       (2)第二種方式:使用Thread.Start方法,這種方式object只能傳單個參數
       //另一種傳遞數據的方式是使用Thread.Start方法(為了應用該方法,在線程中啟動的方法必須接受object類型的單個參數)
var threadTwo = new Thread(Count); threadTwo.Name = "ThreadTwo"; threadTwo.Start(8); threadTwo.Join(); Console.WriteLine("--------------------------");
       (3)第三種方式:使用lambda表達式。lambda表達式定義了一個不屬於任何類的方法
       //我們創建了一個方法,該方法使用需要的參數調用了另一個方法,並在另一個線程中運行該方法
var threadThree = new Thread(() => CountNumbers(12)); threadThree.Name = "ThreadThree"; threadThree.Start(); threadThree.Join(); Console.WriteLine("--------------------------");        
       //當在lambda表達式中使用任何局部變量時, C#會生成一個類,並將該變量作為該類的一個屬性。所以實際上該方式與 threadOne線程中使用的一樣,但是我們無須定義該類, C#編譯器會自動幫我們實現
       
       //這也會導致一個問題,如果在多個lambda表達式中使用相同的變量,它們會共享該變量值
       //它們都會打印20,因為在這兩個線程啟動之前變量被修改為20。
int i = 10; var threadFour = new Thread(() => PrintNumber(i)); i = 20; var threadFive = new Thread(() => PrintNumber(i)); threadFour.Start(); threadFive.Start(); Console.Read(); }

 

運行結果:

 

 

對代碼的分析和總結:

  當主程序啟動時,首先創建了ThreadSample類的一個對象,並提供了一個迭代次數。然后使用該對象的CountNumbers方法啟動線程。該方法運行在另一個線程中,但是使用數字10,該數字是通過ThreadSample對象的構造函數傳入的。因此,我們只是使用相同的間接方式將該迭代次數傳遞給另一個線程。

  另一種傳遞數據的方式是使用Thread.Start方法。該方法會接收一個對象,並將該對象,傳遞給線程。為了應用該方法,在線程中啟動的方法必須接受object類型的單個參數。在創建threadTwo線程時演示了該方式。我們將8作為一個對象傳遞給了Count方法,然后 Count方法被轉換為整型。

  接下來的方式是使用lambda表達式。lambda表達式定義了一個不屬於任何類的方法。我們創建了一個方法,該方法使用需要的參數調用了另一個方法,並在另一個線程中運行該方法。當啟動threadThree線程時,打印出了12個數字,這正是我們通過lambda表達式傳遞,的數字。

  使用lambda表達式引用另一個C#對象的方式被稱為閉包。當在lambda表達式中使用任何局部變量時, C#會生成一個類,並將該變量作為該類的一個屬性。所以實際上該方式與 threadOne線程中使用的一樣,但是我們無須定義該類, C#編譯器會自動幫我們實現。

  這可能會導致幾個問題。例如,如果在多個lambda表達式中使用相同的變量,它們會共享該變量值。在前一個例子中演示了這種情況。當啟動threadFour和threadFive線程時,.它們都會打印20,因為在這兩個線程啟動之前變量被修改為20。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM