C# 异步任务仅运行列表中的最后一个任务

C# 异步任务仅运行列表中的最后一个任务,c#,multithreading,task-parallel-library,C#,Multithreading,Task Parallel Library,我正在努力了解如何更好地利用.NET4.5TPL。传统上,我使用老式的方式管理线程,直接排队和管理线程 我创建了一个愚蠢的程序来探索TPL,但是,代码似乎只执行添加到我的任务列表中的最后一个任务-我无法确定原因: class Program { static void Main(string[] args) { var a = new A(); var b = new B(); var tasks = new List<Task&

我正在努力了解如何更好地利用.NET4.5TPL。传统上,我使用老式的方式管理线程,直接排队和管理线程

我创建了一个愚蠢的程序来探索TPL,但是,代码似乎只执行添加到我的任务列表中的最后一个任务-我无法确定原因:

class Program {
    static void Main(string[] args) {

        var a = new A();
        var b = new B();

        var tasks = new List<Task<string>>();
        for (int j = 33; j < 64; j++) {
            tasks.Add(Task.Run(() => a.Go(j, 20)).ContinueWith((i) => b.Do(i)));
        }
        var finalTask = Task.Factory.ContinueWhenAll(tasks.ToArray(), r => {
            foreach (var t in r)
                Console.Write(t.Result);
        });

        finalTask.Wait();

        Console.WriteLine("Finished.");
        Console.ReadLine();

    }
}

public class A {
    public int Go(int chr, int loops) {
        for (int i = 0; i < loops; i++) {
            Thread.Sleep(10);
            Console.Write((char)chr);
        }
        return loops;
    }
}

public class B {
    public string Do(Task<int> value) {
        string s = "";
        for (int i = 0; i < value.Result; i++) {
            s = s + "a";
        }
        return s;
    }
}
类程序{
静态void Main(字符串[]参数){
var a=新的a();
var b=新的b();
var tasks=新列表();
对于(int j=33;j<64;j++){
tasks.Add(Task.Run(()=>a.Go(j,20)).ContinueWith((i)=>b.Do(i));
}
var finalTask=Task.Factory.ContinueWhenAll(tasks.ToArray(),r=>{
foreach(r中的变量t)
控制台写入(t.Result);
});
finalTask.Wait();
控制台。WriteLine(“完成”);
Console.ReadLine();
}
}
公共A类{
公共int Go(int chr,int循环){
for(int i=0;i

知道为什么其他线程不执行吗?

您必须在闭包上下文中捕获正在运行的变量
j

for (int j = 33; j < 64; j++) {
        var num = j;
        tasks.Add(Task.Run(() => a.Go(num, 20)).ContinueWith((i) => b.Do(i)));
    }
for(int j=33;j<64;j++){
var num=j;
tasks.Add(Task.Run(()=>a.Go(num,20)).ContinueWith((i)=>b.Do(i));
}

另请参见

您必须在闭包上下文中捕获运行变量
j

for (int j = 33; j < 64; j++) {
        var num = j;
        tasks.Add(Task.Run(() => a.Go(num, 20)).ContinueWith((i) => b.Do(i)));
    }
for(int j=33;j<64;j++){
var num=j;
tasks.Add(Task.Run(()=>a.Go(num,20)).ContinueWith((i)=>b.Do(i));
}

另请参见

我讨厌我有一个很好的答案,它不仅解决了捕获问题,而且我不能发布,因为这个该死的问题在写的时候被标记为重复。我强烈建议你看看TAP,而不是浪费时间在TPL上。它建立在相同的基础设施上,但可以平滑许多粗糙的边缘。我有一个答案描述了如何用TAP做你的小实验,但我不能发布它,因为这被标记为重复。我讨厌我有一个伟大的答案,解决了很多不仅仅是捕获问题,我不能发布,因为该死的问题被标记为重复,而写了起来。我强烈建议看TAP而不是浪费时间与TPL。它建立在相同的基础设施上,但可以平滑许多粗糙的边缘。我有一个答案,描述了如何用TAP做你的小实验,但我不能发布它,因为它被标记为重复。