如何在C#中处理/实现多个任务和Parallel.For [英] How to handle/implement multiple Tasks and Parallel.For in C#

查看:88
本文介绍了如何在C#中处理/实现多个任务和Parallel.For的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我需要的项目清单执行大的计算任务,所以我实现了相同的跟随。
如果我在这里做错任何事,请告诉我。

 {
" MainList":[{
" Name":" First item from root task",
" Task":{{
" SubTask1":" ...",
" SubTask2":" ..."
}]
},
{
" Name":" second item from root task",
" Task":{{
" SubTask1":" ...",
" SubTask2":" ...",
" SubTask3":" ...",
"SubTask4":"......"
}]
}
]
}





场景:



  1. 必须对列表中的每个项目执行大型计算任务"MainList"。

  2. 完成MainList中的任何任务后,必须对同一列表中的每个项目执行另一项任务(这必须在T1完成后执行)并且必须执行来自"任务"属性的所有子任务。



请注意,步骤2中的任务都必须在第一个任务完成后执行,然后这两个任务都可以执行paralley。



考虑到上述情况,我开发了如下代码:

 

List< Task< object> ;> mainFirstTaskList = new List< Task< object>>();
List< Task< object>> mainSecondTaskList = new List< Task< object>>();
List< Task> ; subTaskList = new List< Task>();
foreach(MainList中的var itm)
{
mainFirstTaskList.Add(Task.Factory.StartNew< object>(()=>
{
//从迭代中使用"itm"
//对每个项目执行大型计算任务
返回resultFirstMainList;
}));
}
while(mainFirstTaskList.Count> 0)
{
int finishedTask = Task.WaitAny(mainFirstTaskList.ToArray()); //等待任何任务完成
任务< object> t = mainFirstTaskList [finishedTask];
var result = t.Result;

mainFirstTaskList.Remove( mainFirstTaskList [finishedTask]);
//在同一个列表上执行另一个任务
mainSecondTaskList.Add(Task.Factory.StartNew< object>(()=>
{
//使用第一个结果任务完成
//对每个项目执行大型计算任务
返回resultSecondMainList;
}));

//在子项目列表上执行任务
subTaskList.Add(Task.Factory.StartNew< object>(()=>
{
//使用Parallel.For对子任务计算进行分区
//并添加了这个Parallel.For在另一个任务中,因为Parallel.For将在当前线程上对任务进行分区
Parallel.For(1,subItemIndex,i =>
{
//执行大任务计算
});
}));
}




<温泉n style ="text-decoration:underline">如果我在这里做错任何事,请告诉我。




提前致谢!!!



解决方案

你确定你的要求,因为当你到达第二个列表时它们没有意义吗?假设你想在第一个任务中做一些简单的事情,例如多个数字2。在第二个任务中你想要显示结果。这是
可能发生的事情。


//列表= 1,2,3


task1(1)开始为
task1(2)开始

task1(3)开始

task1(1)完成

task2(1)开始

task2(2)开始

task2(3)开始

task2(3)完成


所以基本上,如果你等待任何第一个任务完成然后启动所有第二组任务,那么它们可以在前任任务开始之前执行并完成。如果是这样的话那么为什么不一次只运行它们呢?你' d得到
相同的不一致行为。


似乎更可能的情况是你需要完成一系列任务。每个任务都必须等待其前任完成。您希望在列表上运行此系列任务。所以你可能更像这样。


task1(1)开始

task1(2)开始

task1(3)开始

task1(1)完成

task2(1)开始

task1(2)完成

task2(2) )开始

task2(1)完成

task1(3)完成

task2(3)开始

task2 (2)完成

task2(3)完成


如果这是您需要的情况类型,那么您只需要在相关任务之间设置延续。当每个任务完成时,结果将自动转发到下一个任务。

 var tasks = new List< Task>(); 

foreach(MainList中的var项目)
{
//对于每个项目按以下顺序安排任务
task = Task.Factory.StartNew(() => {})
.ContinueWith(()=> {});

tasks.Add(task);
};

//等待他们全部完成
Task.WaitAll(tasks.ToArray());






I have list of items on which I have to perform big computation task, so I have Implemented the same like following. Please let me know if I am doing any thing wrong here.

{
    "MainList": [{
            "Name": "First item from root task",
            "Task": [{
                "SubTask1": "...",
                "SubTask2": "..."
            }]
        },
        {
            "Name": "Second item from root task",
            "Task": [{
                "SubTask1": "...",
                "SubTask2": "...",
                "SubTask3": "...",
                "SubTask4": "..."
            }]
        }
    ]
}


Scenario:

  1. Have to perform big computational task on each item from list "MainList".
  2. On completion of any of the task from MainList have to perform the another task on each item from same list(this have to perform after T1 gets completed) and in parallel have to perform all the sub tasks from "Tasks" property.

Please note, both the task from STEP 2, have to execute after first task gets completed, and both these task can then execute paralley.

Considering above scenarios, I have developed the code like below:

List<Task<object>> mainFirstTaskList = new List<Task<object>>(); List<Task<object>> mainSecondTaskList = new List<Task<object>>(); List<Task> subTaskList = new List<Task>(); foreach (var itm in MainList) { mainFirstTaskList.Add(Task.Factory.StartNew<object>(() => { //Use "itm" from iteration //Perform big computational task on each item return resultFirstMainList; })); } while (mainFirstTaskList.Count > 0) { int finishedTask = Task.WaitAny(mainFirstTaskList.ToArray()); //waiting for any of the task to gets complete Task<object> t = mainFirstTaskList[finishedTask]; var result = t.Result;

mainFirstTaskList.Remove(mainFirstTaskList[finishedTask]); //Perform Another Task on the same list mainSecondTaskList.Add(Task.Factory.StartNew<object>(() => { //use result from first task completed //Perform big computational task on each item return resultSecondMainList; })); //Perform the task on sub item list subTaskList.Add(Task.Factory.StartNew<object>(() => { //Have used Parallel.For to partition the sub task computation //And have added this Parallel.For inside another Task, as Parallel.For will partition the tasks on current thread Parallel.For(1, subItemIndex, i => { //Perform big task computation }); })); }


Please let me know, if I have did any thing wrong here.

Thanks in advance!!!

解决方案

Are you sure about your requirements because they don't make sense when you get to the second list? Suppose you wanted to do something simple in the first task like multiple a number by 2. In the second task you want to display the result. Here's what could happen.

//List = 1, 2, 3

task1 (1) starts
task1 (2) starts
task1 (3) starts
task1 (1) completes
task2 (1) starts
task2 (2) starts
task2 (3) starts
task2 (3) completes

So basically, if you wait for any of the first tasks to complete and then start all the second set of tasks then they may execute and finish before the predecessor task even starts. If that were the case then why not just run them all at once? You'd get the same inconsistent behavior.

It seems like the more likely scenario is that you have a series of tasks you want to complete. Each task has to wait for its predecessor to complete. You want to run this series of tasks on a list. So you may something more like this.

task1 (1) starts
task1 (2) starts
task1 (3) starts
task1 (1) completes
task2 (1) starts
task1 (2) completes
task2 (2) starts
task2 (1) completes
task1 (3) completes
task2 (3) starts
task2 (2) completes
task2 (3) completes

If this is the type of situation you need then you just need to set up a continuation between the related tasks. As each task completes the results will be automatically forwarded to the next task.

var tasks = new List<Task>();

foreach (var item in MainList)
{
   //For each item schedule the tasks in the following order
   task = Task.Factory.StartNew(() => { })
              .ContinueWith(() => { });

   tasks.Add(task);               
};

//Wait for them all to finish
Task.WaitAll(tasks.ToArray());


这篇关于如何在C#中处理/实现多个任务和Parallel.For的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆