我不会解释为什么使用此代码
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:0
END Thread-------------
START Thread-------------
Print:0
END Thread-------------
为什么第二次打印不显示打印1?
我认为第一次迭代是正确的,因为我看到print:0但是第二次为什么我看不到print:1?
为ANSER编辑
没有[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 :(得分:2)
我认为你在这里并不真正理解ThreadStatic
属性。这意味着,根据定义,Indicates that the value of a static field is unique for every thread.
这意味着该值对于主线程(您创建BackgroundWorkers的位置)和BackgroundWorkers是唯一的,它将始终具有i
的默认值0。 / p>
答案 1 :(得分: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 :(得分:0)
检查'Console.WriteLine(“打印:”+ i);'在lambda里面。 在for循环中,“Print:”+ i不会被评估和连接。它将出现在您的匿名方法中,并且只有在该方法运行时才会连接。
由于您的[ThreadStatic]属性,int i不在线程之间共享。 “每个执行线程都有一个单独的字段实例,并独立设置和获取该字段的值。如果在另一个线程上访问该字段,它将包含不同的值。”
int i将被实例化,你得到int默认值。