我正在处理一个大excel(10k记录),这是一个要求此过程在多个线程上运行以提高性能。
现在,我正在检查ROW< = 2000,那么这是所有记录的fien unrun utils.ixgenerateWithData。但是,如果行> 2000(例如10K),我想将它们分为多个线程,以处理utils.ixgeneratewithdata,每个线程都有2000条记录。
请帮助
using (Stream contentStream = await requestContent.ReadAsStreamAsync())
{
Workbook workbook = new Workbook(contentStream);
Worksheet worksheet = workbook.Worksheets[0];
int column = 0; // first column
Cell lastCell = worksheet.Cells.EndCellInColumn((short)column);
//Run on multiple threads if the file has more than 2000 records
if (lastCell.Row > 2000)
{
//Not sure what to do here
// Infiniti GenerateWithData Web Service
Thread thread = new Thread(() => Utils.IxGenerateWithData(payloadSettings.ProjectGUID, payloadSettings.DatasourceGUID, xmlContent, payloadSettings.InfinitiUsername, payloadSettings.InfinitiPassword, payloadSettings.ServiceWSDL));
thread.Start();
}
else
{
for (int row = 0; row <= lastCell.Row; row++)
{
Cell cell = worksheet.Cells.GetCell(row, column);
xmlContent += cell.StringValueWithoutFormat;
}
// Infiniti GenerateWithData Web Service
Utils.IxGenerateWithData(payloadSettings.ProjectGUID, payloadSettings.DatasourceGUID, xmlContent, payloadSettings.InfinitiUsername, payloadSettings.InfinitiPassword, payloadSettings.ServiceWSDL);
}
}
一个好的开始是确定要启动多少个线程。如果您每线程进行2000行,则将线程计算如下:
var threadCount = (lastCell.Row / 2000) + 1;
添加1个以确保线程将永远不会超过2000行,但可以具有较小的行。
然后计算Rowsperthread如下:
var rowsPerThread = lastCell.Row / threadCount;
最后有一个循环启动线程传递的线程,该行的行阵列应该处理。在这里,我将创建一个在for循环中创建的类,并且其需要处理的行将通过构造函数传递。然后具有启动方法,该方法启动线程以处理对象中的行。
此类类的大纲看起来如下:
public class ExcelRowProcessor()
{
private List<ExcelRow> _rows = new List<ExcelRow>();
public ExcelRowProcessor(IEnumerable<ExcelRow> rows)
{
_rows.AddRange(rows);
}
public void Start()
{
// Start the thread here.
}
}
我希望这会有所帮助。
很抱歉使它成为一个新的答案,但是我还没有声誉,无法在jaco上发布。
无论如何,通常您不想根据工作负载/桶装确定线程数量。最好根据CPU内核确定铲斗大小。这是为了防止线程切换,还允许OS/病毒扫描仪的一个核心也可以提供帮助。
获取线程/核心/过程计数...请参阅此帖子:如何通过.NET/C#?
找到CPU内核的数量var threadCount = cpuCoreCount - 1; //TODO: use code from above URL
if (0 == threadCount) {
threadCount = 1;
}
var rowsPerThread = lastCell.Row / threadCount; // As Jaco posted
所以回到您有关如何线程的问题:
using (Stream contentStream = await requestContent.ReadAsStreamAsync())
{
Workbook workbook = new Workbook(contentStream);
Worksheet worksheet = workbook.Worksheets[0];
int column = 0; // first column
Cell lastCell = worksheet.Cells.EndCellInColumn((short)column);
List<IAsyncResult> asyncResults = new List<IAsyncResult>();
string xmlContent = ""; // assuming this is local
for (int row = 0; row <= lastCell.Row; row++)
{
Cell cell = worksheet.Cells.GetCell(row, column);
xmlContent += cell.StringValueWithoutFormat;
if (((row > 0) && (row % rowsPerThread == 0)) || (rows == lastCell.Row))
{
var caller = new GenerateDelegate(Generate);
asyncResults.Add(caller.BeginInvoke(xmlContent, null, null));
xmlContent = "";
}
}
// Wait for the threads
asyncResults.ForEach(result => {
while(result.IsCompleted == false) {
Thread.Sleep(250);
}
});
}
将此代码放在函数之外
private delegate void GenerateDelegate(string xmlContent);
///<summary>
/// Call Infiniti GenerateWithData Web Service
///<summary>
private void Generate(string xmlContent)
{
Utils.IxGenerateWithData(payloadSettings.ProjectGUID, payloadSettings.DatasourceGUID, xmlContent, payloadSettings.InfinitiUsername, payloadSettings.InfinitiPassword, payloadSettings.ServiceWSDL);
}