Automapper/StructureMap 同步代码的 TPL 版本问题
Automapper/StructureMap issues with TPL version of synchronous code
这是我的同步工作版本,供一些工作人员在给定通用工作负载的情况下执行一些不同的工作:
foreach (var worker in _workers)
{
worker.DoWork(workload);
}
我正在尝试通过任务并行库 (TPL) 利用现有核心:
foreach (var worker in _workers)
{
var worker1 = worker;
await Task.Run(() => worker1.DoWork(workload));
}
await Task.WhenAll();
目的是,每个工作人员都在自己的线程中执行。请注意,此 运行s 在异步方法中,它会不时收到 'workload'。我想确保在 foreach 再次 运行 之前完成所有工作。因此,行:
await Task.WhenAll();
不幸的是,我似乎有一些与 automapper/structuremap 有关的零星映射异常(同步工作正常)。这是我的结构图代码:
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 代码是否存在根本性错误?
Is there something fundamentally wrong with the TPL code?
是的。 await Task.WhenAll()
没有做任何事情,因为它应该接受任务作为参数。并使用 Task.Run
卸载到 ThreadPool
但也不会按顺序等待每个任务。
您可能想做的是:
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
等待所有这些任务的完成。
这是我的同步工作版本,供一些工作人员在给定通用工作负载的情况下执行一些不同的工作:
foreach (var worker in _workers)
{
worker.DoWork(workload);
}
我正在尝试通过任务并行库 (TPL) 利用现有核心:
foreach (var worker in _workers)
{
var worker1 = worker;
await Task.Run(() => worker1.DoWork(workload));
}
await Task.WhenAll();
目的是,每个工作人员都在自己的线程中执行。请注意,此 运行s 在异步方法中,它会不时收到 'workload'。我想确保在 foreach 再次 运行 之前完成所有工作。因此,行:
await Task.WhenAll();
不幸的是,我似乎有一些与 automapper/structuremap 有关的零星映射异常(同步工作正常)。这是我的结构图代码:
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 代码是否存在根本性错误?
Is there something fundamentally wrong with the TPL code?
是的。 await Task.WhenAll()
没有做任何事情,因为它应该接受任务作为参数。并使用 Task.Run
卸载到 ThreadPool
但也不会按顺序等待每个任务。
您可能想做的是:
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
等待所有这些任务的完成。