当我使用线程将内容打印到控制台时,为什么会产生奇怪的结果? [英] When I use threads to print things to the console, why does it produce odd results?
问题描述
最近,我在阅读Rob Robs的非常好的pdf时进入了Threads(此处).他在第160页上有一个示例(2012,C#pdf),但它没有写到控制台,只是执行了空循环.
I've been getting into Threads lately while reading the very nice pdf from Rob Miles (here). He had an example on page 160 (2012, C# pdf) but it didn't write to the console just did empty loops.
我编写了一个非常简单的线程生成循环,该循环创建了10个线程,它们以1000的倍数将其ID写入屏幕.这很好-它向我展示了线程如何一起运行.我的问题始于为什么我的输出如此混乱?通常,当我在下面运行该程序时,我可以肯定地看到多行"Thread 3 Finished"行,我应该只有一行.
I wrote a very simple thread producing loop that creates 10 threads that are writing their IDs to the screen on each multiple of 1000. This was nice - it showed me how threads were running together. My Questions begins with why is my output so confused? Often when I run the program below, I get multiple "Thread 3 Finished" lines where I'm pretty certain, I should only have one of each.
我从MSDN添加了锁定" 循环,但似乎仍会产生奇数输出(我将在下面举例).
I added a "lock" from MSDN to the loop but it still seems to produce odd output (I'll put an example below).
namespace ConsoleApplication1
{
class Program
{
static object sync = new object();
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Thread myThread = new Thread(() => DoThis(i));
myThread.Start();
}
Console.ReadLine();
}
static void DoThis(int s)
{
lock (sync) // a new addition that hasn't helped
{
for (long j = 0; j < 10000; j++)
{
if (j % 1000 == 0) Console.Write(String.Format("{0}.", s));
}
Console.WriteLine("\r\nThread {0} Finished", s);
Debug.Print("\r\nThread {0} Finished", s); //<-- added to debug
}
}
}
}
我以为我做得很好-我有局部变量(我的计数循环),我有一个int大概不是通过引用传递的,后来我尝试在执行它的循环时将其锁定.不高兴,我该怎么做才能使输出看起来很合理?我尝试了Deubg.Print进行故障排除,但它也有错误(如下).
I thought I was doing okay - I have local variables (my counting loop), I have an int that is passed presumably not by reference and later I tried to lock it while doing it's loop. No joy.What would I need to do to make the output look sensible? I tried Deubg.Print to troubleshoot but it has errors too (below).
最终,我想在更大的应用程序中使用线程,但是如果我在这里找不到它,我不确定我想这样做!
Eventually, I want to use threading in a larger application but if I can't get it right here, I'm not sure I want to!
示例从最后的debug.print行输出:(注意倍数)...
Example Output from the debug.print line at the end: (note the multiples) ...
Thread 1 Done
The thread '<No Name>' (0x15cc) has exited with code 0 (0x0).
Thread 9 Done
The thread '<No Name>' (0x1d0c) has exited with code 0 (0x0).
Thread 6 Done
The thread '<No Name>' (0x2248) has exited with code 0 (0x0).
Thread 10 Done
The thread '<No Name>' (0x22bc) has exited with code 0 (0x0).
Thread 9 Done
The thread '<No Name>' (0x85c) has exited with code 0 (0x0).
Thread 9 Done
The thread '<No Name>' (0x1628) has exited with code 0 (0x0).
Thread 3 Done
The thread '<No Name>' (0x2384) has exited with code 0 (0x0).
Thread 6 Done
Thread 2 Done
Thread 4 Done
The thread '<No Name>' (0x2348) has exited with code 0 (0x0).
The thread '<No Name>' (0x2420) has exited with code 0 (0x0).
The thread '<No Name>' (0x1ea8) has exited with code 0 (0x0).
让我知道我是否可以提供有关尝试过的更多信息.
Let me know if I can offer any more info on what I've tried.
推荐答案
您的问题是,您正在对循环变量使用修改后的闭包".
Your problem here is that you are using a "modified closure" on the loop variable.
尽管此问题已在foreach
循环中得到解决,但for
循环仍然存在问题(并将始终存在)
Although this has been fixed for foreach
loops, for
loops still have the issue (and always will)
要修复此问题,请将Main()更改为此:
To fix it, change your Main() to this:
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
int copy = i; // Make a copy of i to prevent the "modified closure" problem.
Thread myThread = new Thread(() => DoThis(copy));
myThread.Start();
}
Console.ReadLine();
}
有关更多详细信息,请参见此处:
See here for more details: