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);
}
}