当我使用线程将内容打印到控制台时,为什么会产生奇怪的结果? [英] When I use threads to print things to the console, why does it produce odd results?

查看:57
本文介绍了当我使用线程将内容打印到控制台时,为什么会产生奇怪的结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我在阅读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:

访问修改后的闭包

查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆