从循环启动线程并传递循环ID [英] Launching a thread from a loop and passing Loop ID

查看:65
本文介绍了从循环启动线程并传递循环ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天才开始玩线程,遇到了一些我不理解的东西.

I just started playing around with threading today and I ran into something that I dont understand.

public void Main()
{ 
    int maxValue = 5;
    for (int ID = 0; ID < maxValue; ID++)
    {
        temp(ID);
    }
}

public void temp(int i)
{
    MessageBox.Show(i.ToString());
}

从基本上讲,它可以正常工作,但是当我尝试为每个线程创建一个新线程时,它只会传递maxValue.请忽略这是多么糟糕的事情,我只是以这种简单的示例的方式编写它.

As basic as it gets which works fine, but when I try to create a new thread for each, it only passes the maxValue. Please disregard how bad this is to do, I only wrote it this way as a simplistic example.

public void Main()
{ 
    int maxValue = 5;
    for (int ID = 0; ID < maxValue; ID++)
    {
        threads.Add(new Thread(() => temp(myString, rowID)));
        threads[rowID].Start();
    }
}

public void temp(string myString, int i)
{
    string _myString = myString;

    MessageBox.Show(i.ToString());
}

鉴于此,我有两个问题: 1)为什么没有在传递ID的新线程上调用方法? 2)如何正确编码?

Given this, I have two questions: 1) Why doesnt a the method get called on a new thread passing the ID? 2) How should this correctly be coded?

推荐答案

问题是您只有一个ID变量,并且该变量已被捕获.仅在实际执行新线程中的代码时(通常在您的主线程完成其循环之后,将ID保留在maxValue处),该变量才被 read 读取.在每次循环迭代中复制一个副本,以便每次捕获一个不同的变量:

The problem is that you've only got one ID variable, and it's being captured. The variable is only being read when the code in the new thread is actually executed, which will often be after your main thread has finished its loop, leaving ID at maxValue. Take a copy on each loop iteration, so that you capture a different variable each time:

for (int ID = 0; ID < maxValue; ID++)
{
    int copy = ID;
    threads.Add(new Thread(() => temp(myString, copy)));
    threads[rowID].Start();
}

这是闭包的常见错误.阅读我比较C#和Java闭包的文章以获得更多信息.顺便说一句,foreach也会发生同样的事情-这更令人困惑,因为它读取就像每次您都有一个新变量一样:

This is a common mistake with closures. Read my article comparing C# and Java closures for more information. The same thing happens with foreach, by the way - and that's even more confusing, as it reads like you've got a new variable each time:

foreach (string url in urls)
{
    // Aargh, bug! Don't do this!
    new Thread(() => Fetch(url)).Start();
}

同样,您最终只会得到一个变量.您需要每个委托来捕获一个单独的变量,因此再次使用一个副本:

Again, you only end up with one variable. You need each delegate to capture a separate variable, so again you use a copy:

foreach (string url in urls)
{
    string urlCopy = url;
    new Thread(() => Fetch(urlCopy)).Start();
}

这篇关于从循环启动线程并传递循环ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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