TPL版本的同步代码的Automapper/StructureMap问题 [英] Automapper/StructureMap issues with TPL version of synchronous code

查看:84
本文介绍了TPL版本的同步代码的Automapper/StructureMap问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的同步工作版本,用于某些工作人员在通用工作负载下可以完成一些不同的工作:

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?

推荐答案

TPL代码从根本上有问题吗?

Is there something fundamentally wrong with the TPL code?

是的. 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问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆