在多个线程中执行可用数据包

时间:2014-07-22 09:36:43

标签: c# .net multithreading

我是C#/。Net的多线程概念的新手,我有以下要求。

我们的应用程序应首先获取需要进行数据处理的客户(仅限ID),并根据WorkPacket的大小(用于将一组客户打包成可用数据包的术语),创建WorkPackets。因此每个工作包都包含一组客户

现在,每个在运行时创建的工作包都需要在不同的线程上执行。因此,所有线程都需要在运行时创建和中止。由于需要处理的客户数量非常庞大,我们将采用多线程概念。

我们有单线程的工作功能,但确定如何使用它实现。以下是使用的代码。任何建议???

public class WorkAllocator
{
    private int workPacketSize;
    private List<WorkPacket> workPackets;
    public List<WorkPacket> WorkPackets
    {
        get { return workPackets; }
        set { workPackets = value; }
    }

    public int WorkPacketSize
    {
        get { return workPacketSize; }
        set { workPacketSize = value; }
    }

    public WorkAllocator(int size)
    {
        workPacketSize = size;
        int noOfPackets=0;
        DataManager objDAL = new DataManager(ConnectionString);

        IEnumerable<string> CustomerIds = objDAL.GetData();
        workPackets = new List<WorkPacket>();

        if (CustomerIds.Count() > 0)
        {
            noOfPackets = CustomerIds.Count() / workPacketSize;
            if (CustomerIds.Count() % workPacketSize != 0)
            {
                noOfPackets++;
            }

            var wps = CustomerIds
                .Select((c, i) => new { Index = i, Value = c })
                .GroupBy(c => c.Index / workPacketSize)
                .Select(c => c.Select(v => v.Value).ToList())
                .ToList();

            foreach (List<string> wp in wps)
            {
                workPackets.Add(new WorkPacket(wp));
            }
        }
        objDAL.Dispose();
    }
}

public class WorkPacket
{
    private List<string> customerIds;

    public List<string> customerIds
    {
        get { return customerIds; }
        set { customerIds = value; }
    }

    public WorkPacket(List<string> Cids)
    {
        customerIds = Cids;
    }
}

主要方法代码

wa = new WorkAllocator(10);
if (wa.WorkPackets != null && wa.WorkPackets.Count > 0)
{
    //Dynamically Create threads for each work packets and join after all child thread completes the activity
    foreach (WorkPacket wp in wa.WorkPackets)
    {
            var _processor = new Processor();
        Processor.Run(wp);
    }
}

2 个答案:

答案 0 :(得分:1)

使用Task的简单解决方案:

wa = new WorkAllocator(10);
if (wa.WorkPackets != null && wa.WorkPackets.Count > 0)
{
    var tasks = new List<Task>();
    foreach (WorkPacket wp in wa.WorkPackets)
    {
        tasks.Add(Task.Run(() =>
            {
                Processor.Run(wp);
            });
    }

    Task.WaitAll(tasks.ToArray());
}

这将在其自己的线程中运行每个Processor(由ThreadPool管理的并行化),然后等待所有这些完成。

也许还会调查ActionBlock,你可以做一些事情:

var threadCount = Environment.ProcessorCount;
var actionBlock = new ActionBlock<WorkPacket>(() => Processor.Run(wp),
   // this is optional, but default is 1:
   new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = threadCount });

wa = new WorkAllocator(10);
if (wa.WorkPackets != null && wa.WorkPackets.Count > 0)
{
    var tasks = new List<Task>();
    foreach (WorkPacket wp in wa.WorkPackets)
        actionBlock.Post(wp);

    actionBlock.Complete();
    actionBlock.Completion.Wait();
}

答案 1 :(得分:1)

在您的主要方法中,您只需使用Parallel.ForEach即可。这是阻止 - 在所有工作包都被处理之前不会返回。

Parallel.ForEach(wa.WorkPackets, wp => Processor.Run(wp));