加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 当多线程时,循环索引超出范围ArgumentOutOfRangeException

发布时间:2020-12-16 00:13:34 所属栏目:百科 来源:网络整理
导读:我得到了一些奇怪的行为……当我在ThreadTest方法中迭代dummyText List时,我得到一个超出范围异常的索引(ArgumentOutOfRangeException),但是如果我删除了线程并且我只是打印出文本,那么一切正常精细. 这是我的主要方法: public static Object sync = new Ob
我得到了一些奇怪的行为……当我在ThreadTest方法中迭代dummyText List时,我得到一个超出范围异常的索引(ArgumentOutOfRangeException),但是如果我删除了线程并且我只是打印出文本,那么一切正常精细.

这是我的主要方法:

public static Object sync = new Object();
static void Main(string[] args)
{
    ThreadTest();
    Console.WriteLine("Press any key to continue.");
    Console.ReadKey();
}

此方法抛出异常:

private static void ThreadTest()
{
    Console.WriteLine("Running ThreadTest");
    Console.WriteLine("Running ThreadTest");
    List<String> dummyText = new List<string>()
    { "One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"};

    for (int i = 0; i < dummyText.Count; i++)
    {
        Thread t = new Thread(() => PrintThreadName(dummyText[i])); // <-- Index out of range?!?
        t.Name = ("Thread " + (i));
        t.IsBackground = true;
        t.Start();
    }
}

private static void PrintThreadName(String text)
{
    Random rand = new Random(DateTime.Now.Millisecond);
    while (true)
    {
        lock (sync)
        {
            Console.WriteLine(Thread.CurrentThread.Name + " running " + text);
            Thread.Sleep(1000+rand.Next(0,2000));
        }
    }
}

这不会抛出异常:

private static void ThreadTest()
{
    Console.WriteLine("Running ThreadTest");
    List<String> dummyText = new List<string>()
    { "One","Ten"};

    for (int i = 0; i < dummyText.Count; i++)
    {
        Console.WriteLine(dummyText[i]); // <-- No exception here
    }
}

有人知道为什么会这样吗?

解决方法

当您通过闭包将局部变量传递给线程或ThreadPool委托时,您需要复制该变量.如:

for (int i = 0; i < dummyText.Count; i++)
{
    int index = i;
    Thread t = new Thread(() => PrintThreadName(dummyText[index]));
    // ...
}

如果你不这样做,那么变量基本上是通过引用传入的,并且索引将超过for循环末尾的数组边界(这可能在执行闭包之前很久就会发生).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读