gpt4 book ai didi

c# - 当我使用线程将内容打印到控制台时,为什么会产生奇怪的结果?

转载 作者:太空狗 更新时间:2023-10-29 18:16:18 26 4
gpt4 key购买 nike

我最近在阅读 Rob Miles (here) 的非常好的 pdf 时开始接触 Threads。他在第 160 页(2012,C# pdf)上有一个例子,但它没有写入控制台,只是做了空循环。

我写了一个非常简单的线程生成循环,它创建了 10 个线程,这些线程在每 1000 的倍数上将它们的 ID 写入屏幕。这很好 - 它向我展示了线程是如何一起运行的。我的问题以为什么我的输出如此困惑开始?通常,当我运行下面的程序时,我会看到多行“Thread 3 Finished”,我很确定,我应该每行只有一个。

我添加了一个 "lock"从 MSDN 到循环,但它似乎仍然产生奇怪的输出(我将在下面举一个例子)。

    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 进行故障排除,但它也有错误(如下)。

最终,我想在更大的应用程序中使用线程,但如果我不能在这里得到它,我不确定我是否想要!

末尾 debug.print 行的示例输出:(注意倍数)...

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).

如果我可以提供更多关于我尝试过的信息,请告诉我。

最佳答案

这里的问题是您在循环变量上使用了“修改后的闭包”。

虽然这已为 foreach 循环修复,但 for 循环仍然存在问题(而且永远都会)

要修复它,请将您的 Main() 更改为:

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();
}

详情请看这里:

Access to Modified Closure

Eric Lippert's Article on Closures

关于c# - 当我使用线程将内容打印到控制台时,为什么会产生奇怪的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16519963/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com