接收错误的参数主题 [英] Threads receiving wrong parameters

查看:114
本文介绍了接收错误的参数主题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在一个线程中的给定参数运行的方法。我注意到,当我运行它, 参数是错误的。对于所举的例子,我有 INT []输出数组用数字1-7。对于每一个数字,我创建了方法的线程 WriteInt(我)。我期望输出为1-7任何顺序,但我不断地看到错过了一些数字和别人重复。这是怎么回事,什么将正确的方法是启动这些线程?

(名单只有那里加入线程后)

 类节目
{
    静态无效的主要(字串[] args)
    {
        INT []输出= {1,2,3,4,5,6,7};

        名单<主题> runningThreads =新的名单,其中,螺纹>();

        的foreach(INT I输出)
        {
            线程线程=新主题(()=> WriteInt(一));
            thread.Start();
            runningThreads.Add(螺纹);
        }
        的foreach(在runningThreads线程t)
        {
            t.Join();
        }
    }

    私有静态无效WriteInt(int i)以
    {
        Console.WriteLine(ⅰ);
    }
}
 

输出示例:

  3
3
4
五
6
7
 

解决方案

由拉姆达创建的闭包(()=> WriteInt(我))是获得收在变量,而不是值设置为每次迭代中。作为线程运行时,它使用在那个时间点,这可能已经由于的foreach 设定值i C $ C>循环处理。

您需要一个临时的:

 的foreach(INT I输出)
{
        INT TEMP =我;
        线程线程=新主题(()=> WriteInt(临时));
        thread.Start();
        runningThreads.Add(螺纹);
}
 

有关所发生的事情的详细信息,请参阅埃里克利珀的一篇名为<一个href="http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx">Closing在循环变量被认为是有害。

此外,在C#5(VS2012),这已不再是一个问题了的foreach 循环。它仍然会然而发生在一个for循环。

I need to run a method with a given parameter in a thread. I've noticed that when I run it, the parameter is wrong. For the example given, I have an array int[] output with the numbers 1-7. For each number, I create a thread with the method WriteInt(i). I expect the output to be 1-7 in any order, but I consistently see some numbers missed and others duplicated. What is going on and what would the correct way be to start these threads?

(The list is only there to join the threads afterwards)

class Program
{
    static void Main(string[] args)
    {
        int[] output = { 1, 2, 3, 4, 5, 6, 7 };

        List<Thread> runningThreads = new List<Thread>();

        foreach (int i in output)
        {
            Thread thread = new Thread(() => WriteInt(i));
            thread.Start();
            runningThreads.Add(thread);
        }
        foreach(Thread t in runningThreads)
        {
            t.Join();
        }
    }

    private static void WriteInt(int i)
    {
        Console.WriteLine(i);
    }
}

Example output:

3
3
4
5
6
7

解决方案

The closure created by the lambda (() => WriteInt(i)) is getting closing over the variable i, not the value set to i within each iteration. As the thread runs, it uses the value set within i at that point in time, which is likely already been changed due to the foreach loop processing.

You need a temporary:

foreach (int i in output)
{
        int temp = i;
        Thread thread = new Thread(() => WriteInt(temp));
        thread.Start();
        runningThreads.Add(thread);
}

For details on what's happening, see Eric Lippert's post titled Closing over the loop variable considered harmful.

Also, in C# 5 (VS2012), this is no longer an issue for foreach loops. It will still happen with a for loop, however.

这篇关于接收错误的参数主题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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