using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ThreadDemo
{
class Program
{
static public List<int> temp = new List<int >();
static public List<Thread> worker = new List<Thread>();
static public List<List<int>> Temporary = new List<List<int>>();
static void Main(string[] args)
{
temp.add(20);
temp.add(10);
temp.add(5);
foreach (int k in temp)
{
int z = 0;
worker[z] = new Thread(() => { sample(k); });
worker[z].Name = "Worker" + z.ToString();
worker[z].Start();
z++;
}
}
public static void sample(int n)
{
List<int> local = new List<int>();
for (int i = 0; i < n; i++)
{
local.Add(i);
}
Temporary.Add(local);
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这个程序中,我在主程序中启动foreach循环时遇到线程问题创建三个线程并启动该线程.在第一个线程操作比其他线程更长所以它需要一些时间但是其他线程在第一个到期之前完成临时更改.i需要临时列表顺序与临时列表顺序相同.我可以使用线程实现此目的
有三个问题.首先,变量捕获:
foreach (int k in temp)
{
int z = 0;
worker[z] = new Thread(() => { sample(k); });
...
}
Run Code Online (Sandbox Code Playgroud)
那是在lambda表达式中捕获变量 k,而不是值的k.解决方案是复制一份:
foreach (int k in temp)
{
int z = 0;
int copy = k;
worker[z] = new Thread(() => { sample(copy); });
...
}
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅Eric Lippert的博客文章.
其次,你总是填充worker[0]因为z永远是0.如果你想填充其他元素,你需要在z外面声明.或者,您可以添加到列表中.
第三,存在不知道结果排序的问题.修复此问题的最简单方法实际上是Temporary变成一个数组.再次,捕获变量的副本以保持正确的位置.正如ArsenMkrt所说,你还需要更新一个涉及锁定的列表.
您使用的是.NET 4.0(或者您可以)吗?Parallel Extensions使所有这些变得更加简单.