如何设置动态并行任务执行而不是手动调用分派?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何设置动态并行任务执行而不是手动调用分派?相关的知识,希望对你有一定的参考价值。
在这种情况下,最佳方法是什么,其中需要运行多个任务,具体取决于给定的参数。请参阅以下代码:
void Mapping()
{
if(param.IsProgram1) {
// spGetProgram1() is a stored procedure call
MapProgram1(context, spGetProgram1().GetIterator());
if(param.IsProgram2) {
MapProgram2(context, spGetProgram2().GetIterator());
}
}
if(param.IsProgram3) {
MapProgram3(context, spGetProgram23().GetIteratior());
}
}
static void MapProgram1(context, IEnumerable<IDataRecord> records) {
// map records to context
}
static void MapProgram2(context, IEnumerable<IDataRecord> records) {
// map records to context
}
static void MapProgram3(context, IEnumerable<IDataRecord> records) {
// map records to context
}
我想重构这个并且并行运行任务。我目前的方法是将任务存储在字典中并根据给定的参数调用它
var tasks = new Dictionary<string, Task<IEnumerable<IDataRecord>>>()
{
{ "MapProgram1", null },
{ "MapProgram2", null },
{ "MapProgram3", null },
}
if(param.IsProgram1) tasks["MapProgram1"].Value = Task.Run(() => spGetProgram1().GetIterator())
... ...
tasks.WaitAll(tasks.Select(t => t.Value).ToArray());
然后获取结果并调用相应的映射方法
foreach(var t in tasks.Where(t => t.Value != null))
{
if(t.Key == "MapProgram1")
{
MapProgram1(context, t.Value.Result);
}
if (t.Key == "MapProgram2")
{
MapProgram2(context, t.Value.Result);
}
.....
}
我确信在这方面有一个更清晰的方法,我不需要手动调用方法。
答案
我不确定我是否按照你的榜样;但是,一般来说,如果你想并行执行任务并有条件地选择要执行的任务,你可能会做这样的事情......
async Task Run() {
List<Task<IResult>> tasks = new List<Task<IResult>>();
if (someCondition) {
tasks.Add(RunSome(someParams));
}
if (othercondition) {
tasks.Add(RunOther(otherParam));
}
IResult[] results = await Task.WhenAll(tasks);
foreach (var result in results) {
if (result is SomeResult someResult) {
// Handle some result
}
else if (result is OtherResult otherResult) {
// Handle other result
}
}
}
static async Task<SomeResult> RunSome(someParams) {
// Run something
}
static async Task<OtherResult> RunOther(otherParams) {
// Run other thing
}
interface IResult {
}
class SomeResult : IResult {
}
class OtherResult: IResult {
}
将要并行执行的任务添加到列表中,让每个任务返回某个结果类型的实例,然后在完成所有任务后检查结果。
另一答案
您可以使用Parallel.ForEach
做很多事情,即调整并行度等
然而,它确实取决于你的工作量和你想要达到的目标,但这可能会让你深思熟虑
var list = new List<Stuff>();
Parallel.ForEach(list, (item) =>
{
switch(item,ConditionType)
{
case ConditionType.First : DoSomethingWithItem(item); break;
case ConditionType.Second : DoSomethingElseWithItem(item); break;
}
});
更多资源
Msdn : How to: Write a Simple Parallel.ForEach Loop
以上是关于如何设置动态并行任务执行而不是手动调用分派?的主要内容,如果未能解决你的问题,请参考以下文章