2016-11-10 99 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默认值。

相关问题