C# 在列表中创建并运行连续任务

C# 在列表中创建并运行连续任务,c#,.net,multithreading,task,C#,.net,Multithreading,Task,我有一个字典,我想创建一个任务列表,我写了这个代码来创建将连续执行的任务列表 var TaskList = new List<Task>(); foreach (var item in this.Values) { if (TaskList.Count == 0) { var task = new Task(item[0]); var LogAct = task.ContinueWith((t) => it

我有一个
字典
,我想创建一个任务列表,我写了这个代码来创建将连续执行的任务列表

var TaskList = new List<Task>();

     foreach (var item in this.Values) {
        if (TaskList.Count == 0) {
           var task = new Task(item[0]);
           var LogAct = task.ContinueWith((t) => item[1](), this.TokenCanc, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
           TaskList.AddRange(new[] { task, LogAct });
        }
        else {
           var task = TaskList[TaskList.Count - 1].ContinueWith((t) => item[0](), this.TokenCanc, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
           var LogAct = task.ContinueWith((t) => item[1](), this.TokenCanc, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
           TaskList.AddRange(new[] { task, LogAct });            
        }
     }
     return TaskList;
  }
我本以为执行从1°任务开始到最新任务,但不幸的是,情况并非如此

例如:

我将操作添加到字典中:

 ActionsLog.Add("T1", new Action[] { () => {
    Console.WriteLine("Test1");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest1") });
 ActionsLog.Add("T2", new Action[] { () => {
    Console.WriteLine("Test2");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest2") });
 ActionsLog.Add("T3", new Action[] { () => {
    Console.WriteLine("Test3");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest3") });
 ActionsLog.Add("T4", new Action[] { () => {
    Console.WriteLine("Test4");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest4") });
 ActionsLog.Add("T5", new Action[] { () => {
    Console.WriteLine("Test5");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest5") });
 ActionsLog.Add("T6", new Action[] { () => {
    Console.WriteLine("Test6"); Thread.Sleep(2000); }, () => Console.WriteLine("LogTest6") });
在任务列表[0].Start()之后,我获得输出:

Test1
LogTest6
Test6
LogTest6
Test6
LogTest6
Test6
LogTest6
Test6
LogTest6
Test6
LogTest6

我可能没有采取正确的方法,但是我如何解决我的问题呢?

不知道你想做什么,但是

Task.Factory.StartNew(()=>{
    foreach(var action in this.Values.SelectMany(x=>x))
        action();
});
希望能有帮助

或许


并尝试使用不同的动作数组调用它。它应该会起作用。如果它不适合你,那么你的数据就有问题。

不确定你想做什么,但是

Task.Factory.StartNew(()=>{
    foreach(var action in this.Values.SelectMany(x=>x))
        action();
});
希望能有帮助

或许


并尝试使用不同的动作数组调用它。它应该会起作用。如果它对你不起作用,那么你的数据就有问题。

我也做了同样的事情,它也起作用了

void Main()
{
var actionlog = new Dictionary<string, Action[]>();
actionlog.Add("T1", new Action[] { () => {
                Console.WriteLine("Test1");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest1") });
actionlog.Add("T2", new Action[] { () => {
                Console.WriteLine("Test2");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest2") });
actionlog.Add("T3", new Action[] { () => {
                Console.WriteLine("Test3");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest3") });
actionlog.Add("T4", new Action[] { () => {
                Console.WriteLine("Test4");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest4") });
actionlog.Add("T5", new Action[] { () => {
                Console.WriteLine("Test5");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest5") });
actionlog.Add("T6", new Action[] { () => {
                Console.WriteLine("Test6"); Thread.Sleep(2000); }, () => Console.WriteLine("LogTest6") });

var task = GetTaskChain(actionlog);

task.Start();
}

public Task GetTaskChain(Dictionary<string, Action[]> actionlog)
{
CancellationToken token = new CancellationToken();
var TaskList = new List<Task>();

foreach (var item in actionlog.Values)
{
    if (TaskList.Count == 0)
    {
        var task = new Task(item[0]);
        var LogAct = task.ContinueWith((t) => item[1](), token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
        TaskList.AddRange(new[] { task, LogAct });
    }
    else
    {
        var task = TaskList[TaskList.Count - 1].ContinueWith((t) => item[0](), token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
        var LogAct = task.ContinueWith((t) => item[1](), token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
        TaskList.AddRange(new[] { task, LogAct });
    }
}
return TaskList[0];
}  
void Main()
{
var actionlog=新字典();
actionlog.Add(“T1”,新操作[]{()=>{
Console.WriteLine(“Test1”);Thread.Sleep(2000);},()=>Console.WriteLine(“LogTest1”)};
actionlog.Add(“T2”,新操作[]{()=>{
Console.WriteLine(“Test2”);Thread.Sleep(2000);},()=>Console.WriteLine(“LogTest2”)};
actionlog.Add(“T3”,新操作[]{()=>{
Console.WriteLine(“Test3”);Thread.Sleep(2000);},()=>Console.WriteLine(“LogTest3”)};
actionlog.Add(“T4”,新操作[]{()=>{
Console.WriteLine(“Test4”);Thread.Sleep(2000);},()=>Console.WriteLine(“LogTest4”)};
actionlog.Add(“T5”,新操作[]{()=>{
Console.WriteLine(“Test5”);Thread.Sleep(2000);},()=>Console.WriteLine(“LogTest5”)};
actionlog.Add(“T6”,新操作[]{()=>{
Console.WriteLine(“Test6”);Thread.Sleep(2000);},()=>Console.WriteLine(“LogTest6”)};
var task=GetTaskChain(actionlog);
task.Start();
}
公共任务GetTaskChain(字典操作日志)
{
CancellationToken=新的CancellationToken();
var TaskList=新列表();
foreach(actionlog.Values中的var项)
{
如果(TaskList.Count==0)
{
var任务=新任务(项目[0]);
var LogAct=task.ContinueWith((t)=>item[1](),token,TaskContinuationOptions.OnlyOnRanToCompletion,TaskScheduler.Default);
TaskList.AddRange(新[]{task,LogAct});
}
其他的
{
var task=TaskList[TaskList.Count-1].ContinueWith((t)=>item[0](),令牌,TaskContinuationOptions.OnlyOnRanToCompletion,TaskScheduler.Default);
var LogAct=task.ContinueWith((t)=>item[1](),token,TaskContinuationOptions.OnlyOnRanToCompletion,TaskScheduler.Default);
TaskList.AddRange(新[]{task,LogAct});
}
}
返回任务列表[0];
}  

我也做了同样的事情,而且效果很好

void Main()
{
var actionlog = new Dictionary<string, Action[]>();
actionlog.Add("T1", new Action[] { () => {
                Console.WriteLine("Test1");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest1") });
actionlog.Add("T2", new Action[] { () => {
                Console.WriteLine("Test2");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest2") });
actionlog.Add("T3", new Action[] { () => {
                Console.WriteLine("Test3");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest3") });
actionlog.Add("T4", new Action[] { () => {
                Console.WriteLine("Test4");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest4") });
actionlog.Add("T5", new Action[] { () => {
                Console.WriteLine("Test5");Thread.Sleep(2000);}, () => Console.WriteLine("LogTest5") });
actionlog.Add("T6", new Action[] { () => {
                Console.WriteLine("Test6"); Thread.Sleep(2000); }, () => Console.WriteLine("LogTest6") });

var task = GetTaskChain(actionlog);

task.Start();
}

public Task GetTaskChain(Dictionary<string, Action[]> actionlog)
{
CancellationToken token = new CancellationToken();
var TaskList = new List<Task>();

foreach (var item in actionlog.Values)
{
    if (TaskList.Count == 0)
    {
        var task = new Task(item[0]);
        var LogAct = task.ContinueWith((t) => item[1](), token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
        TaskList.AddRange(new[] { task, LogAct });
    }
    else
    {
        var task = TaskList[TaskList.Count - 1].ContinueWith((t) => item[0](), token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
        var LogAct = task.ContinueWith((t) => item[1](), token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
        TaskList.AddRange(new[] { task, LogAct });
    }
}
return TaskList[0];
}  
void Main()
{
var actionlog=新字典();
actionlog.Add(“T1”,新操作[]{()=>{
Console.WriteLine(“Test1”);Thread.Sleep(2000);},()=>Console.WriteLine(“LogTest1”)};
actionlog.Add(“T2”,新操作[]{()=>{
Console.WriteLine(“Test2”);Thread.Sleep(2000);},()=>Console.WriteLine(“LogTest2”)};
actionlog.Add(“T3”,新操作[]{()=>{
Console.WriteLine(“Test3”);Thread.Sleep(2000);},()=>Console.WriteLine(“LogTest3”)};
actionlog.Add(“T4”,新操作[]{()=>{
Console.WriteLine(“Test4”);Thread.Sleep(2000);},()=>Console.WriteLine(“LogTest4”)};
actionlog.Add(“T5”,新操作[]{()=>{
Console.WriteLine(“Test5”);Thread.Sleep(2000);},()=>Console.WriteLine(“LogTest5”)};
actionlog.Add(“T6”,新操作[]{()=>{
Console.WriteLine(“Test6”);Thread.Sleep(2000);},()=>Console.WriteLine(“LogTest6”)};
var task=GetTaskChain(actionlog);
task.Start();
}
公共任务GetTaskChain(字典操作日志)
{
CancellationToken=新的CancellationToken();
var TaskList=新列表();
foreach(actionlog.Values中的var项)
{
如果(TaskList.Count==0)
{
var任务=新任务(项目[0]);
var LogAct=task.ContinueWith((t)=>item[1](),token,TaskContinuationOptions.OnlyOnRanToCompletion,TaskScheduler.Default);
TaskList.AddRange(新[]{task,LogAct});
}
其他的
{
var task=TaskList[TaskList.Count-1].ContinueWith((t)=>item[0](),令牌,TaskContinuationOptions.OnlyOnRanToCompletion,TaskScheduler.Default);
var LogAct=task.ContinueWith((t)=>item[1](),token,TaskContinuationOptions.OnlyOnRanToCompletion,TaskScheduler.Default);
TaskList.AddRange(新[]{task,LogAct});
}
}
返回任务列表[0];
}  

这看起来像是一个关闭问题。 查看您的编译器。
在旧版本中,
foreach
循环保留对最后一个委托的引用。
例如,对于旧的编译器版本,此代码将打印
3
,对于新的编译器版本,此代码将打印
13

var numbers = new int[] { 1, 2, 3 };
var actions = new List<Action>();
foreach (var number in numbers)
    actions.Add(() => Console.WriteLine(number));
foreach (var action in actions)
    action();
var numbers=newint[]{1,2,3};

var actions=新列表和

这看起来像是一个关闭问题。 查看您的编译器。
在旧版本中,
foreach
循环保留对最后一个委托的引用。
例如,对于旧的编译器版本,此代码将打印
3
,对于新的编译器版本,此代码将打印
13

var numbers = new int[] { 1, 2, 3 };
var actions = new List<Action>();
foreach (var number in numbers)
    actions.Add(() => Console.WriteLine(number));
foreach (var action in actions)
    action();
var numbers=newint[]{1,2,3};

var actions=新列表和

我有科特建议我的解决方案

对于编译器版本v4.0.303191,问题是“ClosureAndForeach”。 代码解决方案是:

var list = new List<Action>();
     foreach (int i in Enumerable.Range(1, 10)) {
        DisplayClass c = new DisplayClass();
        c.i = i;
        list.Add(c.getAct());
     }
     foreach (Action action in list)
        action();

谢谢大家

我有科特建议我的解决方案

对于编译器版本v4.0.303191,问题是“ClosureAndForeach”。 代码解决方案是:

var list = new List<Action>();
     foreach (int i in Enumerable.Range(1, 10)) {
        DisplayClass c = new DisplayClass();
        c.i = i;
        list.Add(c.getAct());
     }
     foreach (Action action in list)
        action();

谢谢大家

感谢您的回答,我想使用列表中添加的第一个任务中的.ContinueWith方法创建一个连续任务执行。不工作:(我尝试了您的方法,但我总是以d.Values执行最新的操作…。与我的问题相同…:(谢谢!我复制/粘贴了您的代码…但s
private sealed class DisplayClass {
     public int i;

     public Action getAct() {
        return () => Console.WriteLine(i);
     }
     public void Action() {
        Console.WriteLine(i);
     }
  }