2016-11-10 53 views
-3

我不爲什麼這段代碼理解爲什麼線程計數沒有增加

static void Main(string[] args) 
    { 
     Console.WriteLine("START PROGRAMN-----------------------------------"); 
     test(); 
     Console.WriteLine("END PROGRAMN-----------------------------------"); 
     Console.Read(); 
    } 
    [ThreadStatic] 
    private static int i; 
    private static void test() 
    { 
     for (i = 0; i < 2; i++) 
     { 
      var bw = new BackgroundWorker(); 

      // define the event handlers 
      bw.DoWork += (sender, args) => 
      { 
       Console.WriteLine("START Thread-------------"); 
       Console.WriteLine("Print:" + i); 
      }; 
      bw.RunWorkerCompleted += (sender, args) => 
      { 
       Console.WriteLine("END Thread-------------"); 
       if (args.Error != null) 
       { 
        Console.WriteLine(args.Error.ToString()); 
       } 
      }; 

      bw.RunWorkerAsync(); // starts the 
     } 
    } 

它會在控制檯中顯示此unrdersntat:

START PROGRAMN----------------------------------- 
END PROGRAMN----------------------------------- 
START Thread------------- 
Print:0 
END Thread------------- 
START Thread------------- 
Print:0 
END Thread------------- 

爲什麼第二打印不顯示打印1?

我認爲第一次迭代是正確的,因爲我看到print:0但是在第二個爲什麼我看不到print:1?

FOR ANSER

EDIT沒有[ThreadStatic]

static void Main(string[] args) 
    { 
     Console.WriteLine("START PROGRAMN-----------------------------------"); 
     test(); 
     Console.WriteLine("END PROGRAMN-----------------------------------"); 
     Console.Read(); 
    } 
    [ThreadStatic] 
    private static int i; 
    private static void test() 
    { 
     for (i = 0; i < 2; i++) 
     { 
      var bw = new BackgroundWorker(); 

      // define the event handlers 
      bw.DoWork += (sender, args) => 
      { 
       Console.WriteLine("START Thread-------------"); 
       Console.WriteLine("Print:" + i); 
      }; 
      bw.RunWorkerCompleted += (sender, args) => 
      { 
       Console.WriteLine("END Thread-------------"); 
       if (args.Error != null) 
       { 
        Console.WriteLine(args.Error.ToString()); 
       } 
      }; 

      bw.RunWorkerAsync(); // starts the 
     } 
    } 

它會在控制檯中顯示此:

START PROGRAMN----------------------------------- 
END PROGRAMN----------------------------------- 
START Thread------------- 
Print:2 
END Thread------------- 
START Thread------------- 
Print:2 
END Thread------------- 

爲什麼第一pirnt不顯示打印0和第二打印1?

爲什麼顯示2?

+0

爲什麼你把它標記爲ASP.NET? – mason

回答

1

忘掉那個ThreadStatic你沒有正確使用它。這不是你需要的情況。您試圖繞過的問題是因爲否則您的結果將獲取最新值,因爲DoEvent未在第一個已經更改的線程上啓動。你最終會遇到競爭狀況。您確實需要使用參數來清晰地顯示變量的本地實例。最簡單的方法是像這樣更改代碼

for (int i = 0; i < 2; i++) 
{ 
    var bw = new BackgroundWorker(); 

    // define the event handlers 
    bw.DoWork += (sender, args) => 
    { 
      // get the argument 
      var value = args.Argument.ToString(); 
      Console.WriteLine("START Thread-------------"); 
      Console.WriteLine("Print:" + value); 
    }; 
    bw.RunWorkerCompleted += (sender, args) => 
    { 
     Console.WriteLine("END Thread-------------"); 
     if (args.Error != null) 
     { 
      Console.WriteLine(args.Error.ToString()); 
     } 
    }; 

    bw.RunWorkerAsync(i); // starts the thread with arguments 
} 
2

我想你並不真正瞭解這裏的ThreadStatic屬性。這意味着,根據定義,Indicates that the value of a static field is unique for every thread.這意味着該值對於主線程(您創建BackgroundWorkers的位置)和BackgroundWorkers是唯一的,對於i,它始終具有默認值0。

0

檢查您的'Console.WriteLine(「Print:」+ i);'在lambda裏面。 「Print:」+ i在for循環內不進行評估和連接。它將出現在您的匿名方法中,並且只有在該方法運行時纔會連接。

由於您的[ThreadStatic]屬性,int i不在線程之間共享。 「每個正在執行的線程都有一個單獨的字段實例,並獨立設置並獲取該字段的值。如果該字段在不同的線程中訪問,它將包含不同的值。」

int我將被實例化,你會得到int默認值。

相關問題