C# 带条件的并行调用
我有一个场景,我想调用函数,但希望它们被有条件地调用。因此,在下面的代码中,只调用函数2和3。但是,动作部分不返回值,但在我的例子中,我希望存储返回值C# 带条件的并行调用,c#,task,parallel.foreach,parallel.invoke,C#,Task,Parallel.foreach,Parallel.invoke,我有一个场景,我想调用函数,但希望它们被有条件地调用。因此,在下面的代码中,只调用函数2和3。但是,动作部分不返回值,但在我的例子中,我希望存储返回值 List<int> list = new List<int> {2,3}; Dictionary<int, Action> actions = new Dictionary<int, Action>() { {1, Function1}, {2, Function2}, {3, F
List<int> list = new List<int> {2,3};
Dictionary<int, Action> actions = new Dictionary<int, Action>()
{
{1, Function1},
{2, Function2},
{3, Function3}
};
Parallel.Invoke((from action in list select actions[action]).ToArray());
如果您需要执行的结果,
Parallel
和Action
将无法获得函数结果,但是如果我们使用Task
和Func
可以在并行运行后获得结果
我在下面的示例中添加了使用Task
而不是Parallel
使函数同时运行并允许您存储结果。我假设函数1、2和3的返回类型为int
,您可以根据需要更改它
List<int> list = new List<int> { 2, 3 };
Dictionary<int, Func<int>> actions = new Dictionary<int, Func<int>>()
{
{1, Function1},
{2, Function2},
{3, Function3}
};
List<Task<int>> taskList = (from a in list select Task.Run(actions[a])).ToList();
// Allow all processing to finish before accessing results
Task.WaitAll(taskList.ToArray());
int result = taskList[0].Result;
List List=新列表{2,3};
字典操作=新建字典()
{
{1,函数1},
{2,函数2},
{3,函数3}
};
List taskList=(从列表中选择Task.Run(actions[a])).ToList();
//允许在访问结果之前完成所有处理
Task.WaitAll(taskList.ToArray());
int result=taskList[0]。结果;
最后请注意,您可以将
taskList.ForEach(…)
与Parallel.ForEach(…)
进行交换,但我认为这将引入一些不必要的开销。如果我学习正确,您只需要执行列表中的一些操作。为什么不直接写在C#上呢
var hs=newhashset{2,3};
var actions=newdictionary()
{
{1,函数1},
{2,函数2},
{3,函数3}
};
actions.Where(x=>hs.Contains(x.Key)).AsParallel().ForAll(x=>x.Value());
他们的阅读方式:获取一组所需密钥(本例中为2和3)中包含密钥的所有对,然后以并行方式执行它们的操作。我想很清楚
如果要返回一些值,请分别使用
Func
和Select
,而不是Action
和ForAll
。我现在正在处理一些并行任务,我使用的是parallel.Invoke。最后,我切换了调用列表中的操作的方式,并调用了parallel.ForEach。结果我每排剃掉1.2毫秒。太棒了。所以我想我会试试你的要求
int Function1(int input)
{
return 10 * input;
}
int Function2(int input)
{
return 20 * input;
}
int Function3(int input)
{
return 30 * input;
}
List<int> list = new List<int> { 2, 3 };
Dictionary<int, Func<int, int>> actions = new Dictionary<int, Func<int, int>>()
{
{1, (arg) => Function1(arg)},
{2, (arg) => Function2(arg)},
{3, (arg) => Function3(arg)}
};
var bag = new ConcurrentBag<int>();
Parallel.ForEach(actions, action => {
if(action.Key == 2 || action.Key == 3)
{
bag.Add(action.Value.Invoke(3));
}
});
foreach(var number in bag)
{
Console.WriteLine(number);
}
int函数1(int输入)
{
返回10*输入;
}
int函数2(int输入)
{
返回20*输入;
}
int函数3(int输入)
{
返回30*输入;
}
列表=新列表{2,3};
字典操作=新建字典()
{
{1,(arg)=>Function1(arg)},
{2,(arg)=>Function2(arg)},
{3,(arg)=>Function3(arg)}
};
var bag=新的ConcurrentBag();
Parallel.ForEach(actions,action=>{
if(action.Key==2 | | action.Key==3)
{
bag.Add(action.Value.Invoke(3));
}
});
foreach(袋中的var编号)
{
控制台写入线(编号);
}
我认为您试图做的是有条件地调用这些方法,然后存储这些函数的返回。我有点困惑,因为您使用的是Action(不返回任何内容)。所以我把它们切换到Func,它是一个取int,返回和int的函数。我还添加了一些内联函数,这样代码就可以通过复制和粘贴运行
若你们想玩一玩的话,这里还有一个.net的提琴 对于未调用的函数,应该返回什么?为什么要使用构造函数创建
任务
,然后调用开始
,而不是只使用任务。运行
?很好,我在使用并行。ForEach
,但没有正确切换回任务
。最好的解决方案是使用Task.Run
而不是Task.Start
。
var hs = new HashSet<int> { 2, 3 };
var actions = new Dictionary<int, Action>()
{
{1, Function1},
{2, Function2},
{3, Function3}
};
actions.Where(x => hs.Contains(x.Key)).AsParallel().ForAll(x => x.Value());
int Function1(int input)
{
return 10 * input;
}
int Function2(int input)
{
return 20 * input;
}
int Function3(int input)
{
return 30 * input;
}
List<int> list = new List<int> { 2, 3 };
Dictionary<int, Func<int, int>> actions = new Dictionary<int, Func<int, int>>()
{
{1, (arg) => Function1(arg)},
{2, (arg) => Function2(arg)},
{3, (arg) => Function3(arg)}
};
var bag = new ConcurrentBag<int>();
Parallel.ForEach(actions, action => {
if(action.Key == 2 || action.Key == 3)
{
bag.Add(action.Value.Invoke(3));
}
});
foreach(var number in bag)
{
Console.WriteLine(number);
}