我试图同时启动多个线程,但它不起作用。这是我的代码:
var previous = 0;
var threadList = new List<Thread> {};
for (var i = (int)partSize; i <= responseLength; i = i + (int)partSize)
{
var t = new Thread(() => Download(URL, previous, i));
//t.Name = i.ToString();
threadList.Add(t);
//t.Start();
//t.Join(300);
//new Thread(() => {Download(URL,previous, i);}).Start();
//var t = Task.Factory.StartNew(() => Download(URL, previous, i));
previous = i;
}
foreach (Thread t in threadList)
{
//Console.WriteLine(t.Name);
t.Start();
}
输出:
77296,86958
77296,86958
77296,86958
77296,86958
77296,86958
77296,86958
77296,86958
77296,86958
显示一段时间后,它挂起并最终崩溃。
不同代码的预期输出:
for (var i = (int)partSize; i <= responseLength; i = i + (int)partSize)
{
var copy = previous;
var t = new Thread(() => Download(URL, copy, i));
t.Start();
t.Join();
previous = i;
}
输出:
0,9662
9662,19324
19324,28986
28986,38648
38648,48310
48310,57972
57972,67634
67634,77296
对于输出,第一个数字表示从哪里开始下载文件的一部分,第二个数字表示从哪里完成(以字节为单位) 如何使用我分配给它的参数来启动列表中的每个线程?我迷路了,所以任何帮助都会很棒。谢谢!
最佳答案
您的 lambda 表达式 () => Download(URL, previous, i)
正在捕获循环变量 i
。捕获的不是值,而是变量本身。因此,当执行对 Download
的调用时,i
可能已经发生了变化。 previous
变量也存在同样的问题,该变量也在循环的迭代之间共享。
解决方法是在循环内声明一个变量,将 i
的值复制到其中,然后在 lambda 中使用该变量(并对 上一个
)。
for (var i = (int)partSize; i <= responseLength; i = i + (int)partSize)
{
var previous2 = previous;
var i2 = i;
var t = new Thread(() => Download(URL, previous2, i2));
参见this article by Eric Lippert以获得更完整的解释。
关于c# - 如何异步启动线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29836586/