如何将Excel行分成多个相等的批次和过程中的过程

  • 本文关键字:过程 过程中 Excel c# excel linq
  • 更新时间 :
  • 英文 :


我正在处理一个大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);
}

最新更新