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);
}
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();
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();
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));
}
}
To isolate the problem, is there something fundamentally wrong with the TPL code to start with?
Yes.
await Task.WhenAll()
doesn't do anything as it's supposed to accept tasks as parameters. And offloading to theThreadPool
withTask.Run
but awaiting each task sequentially doesn't either.What you probably wanted to do is this:
Or more simply this:
Which creates a task for each worker that will run on the
ThreadPool
and then usesTask.WhenAll
to await the completion of all these tasks.