优选的大小列表的动态块

时间:2018-02-20 11:48:45

标签: c# arrays list split

所以我遇到了一些块状平衡。

我面临的问题是我有一个n长度列表(最常见的是400到10000之间)

我希望将这些内容组合起来并发送给一系列工作人员,同时进行处理。

所以这是我的要求。

块的数量应始终保持尽可能高,但最好不要超过8,因为这是一次可以处理的最大数量,不得超过8个块必须排队。

零件的长度应保存在250到1000之间甚至50的容器中(这样可以更容易地跟踪日志中的块)

示例
清单长度为1600
6块250块和1块100块

列表长度3590
7块450块和1块440块

13000的清单 13块1000块(因为工人最多只能处理1000件) 在发送新内容之前,我将不得不等待大块的完成。

我需要自动选择以最大限度地提高效率。

以下是我正在做的事情的简化基础

public async Task SartSendingJob(int entityId, string body, string reference, IEnumerable<ProcessObject> processingList)
    {
        var jobId = Guid.NewGuid();
        _jobs.Add(new Job {EntityId = entityId, Id = jobId, ProcessType = ProcessType.Demo});

        var chunks = Split(processingList);

        foreach (var chunk in chunks)
        {
            var process = new Process {JobId = jobId, Id = Guid.NewGuid()};
            _processes.Add(process);

            Sender.SendSimpleMessage("PressRelease", body, reference, chunk.ToList(), process.Id);
        }
    }

    private IEnumerable<IEnumerable<T>> Split<T>(IEnumerable<T> list)
    {
        var workList = list.ToList();
        int chunksize;
        if (list.Count() > 8000)
        {
            //We know that we can't get lett then 8 chunks of maxumum, so we will use maxumum chunk size
            chunksize = 1000;
        }
        else
        {
            chunksize = CalculateBestChunkSize(workList.Count);
        }

        var sections = (int)Math.Ceiling((double)workList.Count / chunksize);

        int i = 0;

        IEnumerable<IEnumerable<T>> splits = workList.GroupBy(item => i++ % sections).Select(part => part.AsEnumerable());
        return splits;

    }

    private int CalculateBestChunkSize(int length)
    {
        //Do some magic
        return 500; //dummy response
    }

2 个答案:

答案 0 :(得分:0)

请尝试以下操作:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Serialization;
using System.IO;


namespace ConsoleApplication23
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] lengths = { 45, 200, 1600, 3500, 13000 };

            foreach (int len in lengths)
            {

                int totalLen = len;
                do
                {
                    int processLen = totalLen > 8000 ? 8000 : totalLen;
                    totalLen -= 8000;

                    int numChunks = 8;
                    int chunkSize = 0;
                    for (; (numChunks > 0) && (chunkSize < 50); numChunks--)
                    {
                        chunkSize = processLen / numChunks;
                    }
                    chunkSize = 50 * (chunkSize / 50);
                    int lastChunk = processLen - (chunkSize * numChunks);
                    Console.WriteLine(" Number of Chunks '{0}', Chunk Size = '{1}', Total Size = '{2}'", numChunks, chunkSize, (numChunks * chunkSize) + lastChunk);
                } while (totalLen > 0);



            }

        }
    }



}

答案 1 :(得分:0)

我的大脑让它变得更加困难。

需要一些咖啡来了解它实际上在做什么。

处理它的解决方案(因为我们总是将块大小超过最大线程)

    private IEnumerable<IEnumerable<T>> Split<T>(List<T> list)
    {
        int chunkSize;
        if (list.Count() > _maxChunkSize * _maxSendingThreads )
        {
            //We know that we can't get lett then 8 chunks of maxumum, so we will use maxumum chunk size
            chunkSize = 1000;
        }
        else
        {
            //Get the exact number of needed chunksize needed, then round up to nearest 50
            chunkSize = (int) (Math.Ceiling(list.Count / _maxSendingThreads / 50.0) * 50.0);
            if (chunkSize < 250)
            {
                chunkSize = 250;
            }
        }

        var sections = (int) Math.Ceiling((double) list.Count / chunkSize);

        int i = 0;

        IEnumerable<IEnumerable<T>> splits = list.GroupBy(item => i++ % sections).Select(part => part.AsEnumerable());
        return splits;
    }