所以我遇到了一些块状平衡。
我面临的问题是我有一个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
}
答案 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;
}