c# - 如何异步启动线程?

标签 c# multithreading download lambda

我试图同时启动多个线程,但它不起作用。这是我的代码:

        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/

相关文章:

自动下载内容的 iOS 应用程序(关于 App Store 政策)

Android 从 Api 下载 Zip 并存储在 SD 卡中

c# - Entity Framework - COUNT 而不是 SELECT

javascript - 无法修改 Controls 集合,因为该控件包含代码块(即 <% ... %>)。Telerik.Web.UI.RadAjaxControl.MoveUpdatePanel

c# - 我们如何在 VC++ 中使用 .NET dll?

c# - 为什么 DateTime.Now 需要线程安全?

c# - ASP.Net 普通类中的静态类

php - 我在处理数据时是否需要锁定我的记录以避免不一致?

c# - 跳过已在使用的锁定部分

c++ - 使用 Libcurl 从 FTP 服务器文件下载多个文件