问题描述
这是我的同步工作版本,用于某些工作人员在通用工作负载下可以完成一些不同的工作:
This is my synchronous working version for some workers to do some different work given a generic workload:
foreach (var worker in _workers)
{
worker.DoWork(workload);
}
我正在尝试通过任务并行库(TPL)利用现有内核:
I am trying to exploit existing cores via the task parallel library (TPL) using this:
foreach (var worker in _workers)
{
var worker1 = worker;
await Task.Run(() => worker1.DoWork(workload));
}
await Task.WhenAll();
目的是,每个工作程序都在其自己的线程中执行.请注意,这是在异步方法中运行的,该方法会不时收到工作量".我想确保在再次运行foreach之前完成所有工作.因此,该行:
The intention is, that each worker is executed in its own thread. Please note that this runs in a async method, which receives a 'workload' from time to time. I want to ensure that all work is done before the foreach is run again. Hence, the line:
await Task.WhenAll();
不幸的是,我似乎有一些与automapper/structuremap有关的零星映射异常(它可以同步正常工作).这是我的结构图代码:
Unfortunately I seem to have some sporadic mapping exception related to automapper/structuremap (it works fine synchronously). This is my structuremap code:
public class MyRegistry : Registry
{
public MyRegistry()
{
For<ISomething>().Singleton().Use<SomethingConcrete>();
var profiles =
from t in typeof(MyRegistry).Assembly.GetTypes()
where typeof(Profile).IsAssignableFrom(t)
select (Profile)Activator.CreateInstance(t);
var config = new MapperConfiguration(cfg =>
{
foreach (var profile in profiles)
{
cfg.AddProfile(profile);
}
});
For<MapperConfiguration>().Use(config);
For<IMapper>().Use(ctx => ctx.GetInstance<MapperConfiguration>().CreateMapper(ctx.GetInstance));
}
}
为找出问题所在,TPL代码从根本上有问题吗?
To isolate the problem, is there something fundamentally wrong with the TPL code to start with?
推荐答案
是的. await Task.WhenAll()
不执行任何操作,因为它应该接受任务作为参数.并使用Task.Run
卸载到ThreadPool
,但是依次等待每个任务也不会.
Yes. await Task.WhenAll()
doesn't do anything as it's supposed to accept tasks as parameters. And offloading to the ThreadPool
with Task.Run
but awaiting each task sequentially doesn't either.
您可能想做的是这样:
var tasks = new List<Task>();
foreach (var worker in _workers)
{
tasks.Add(Task.Run(() => worker.DoWork(workload)));
}
await Task.WhenAll(tasks);
或更简单地说:
await Task.WhenAll(_workers.Select(worker => Task.Run(() => worker .DoWork(workload)));
为每个将在ThreadPool
上运行的工作程序创建一个任务,然后使用Task.WhenAll
等待所有这些任务的完成.
Which creates a task for each worker that will run on the ThreadPool
and then uses Task.WhenAll
to await the completion of all these tasks.
这篇关于TPL版本的同步代码的Automapper/StructureMap问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!