2016-12-07 3 views
0

큰 엑셀 (10k 레코드)을 처리하고 있으며이 프로세스를 성능을 향상 시키려면 여러 스레드에서 실행해야합니다.분할하는 방법 행을 여러 개의 동일한 로트와 반복 처리하는 방법

지금은 행 < = 2000이면 확인하고 있는데, 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); 
           }        
          } 
+0

나는 당신을 도울 수 있는지 모르겠지만 왜 "수익률"을 사용하지 않습니까? http://www.ytechie.com/2009/02/using-c-yield-for-readability-and-performance/ –

답변

0

가 좋은 시작이 시작하려는 얼마나 많은 스레드를 결정하는 것입니다 도와주세요.

var threadCount = (lastCell.Row/2000) + 1; 

1 스레드가 2000 개 이상의 행이하지 않습니다하지만 덜을 수 있도록 추가됩니다 : 당신이 스레드 당 2,000 행을하려는 경우 다음과 같이 다음 THREADCOUNT 계산 될 것이다. 다음

이어서 rowsPerThread을 계산 :

var rowsPerThread = lastCell.Row/threadCount; 

는 마지막 반복에 대한 그것에게 그것이 처리해야 행의 배열을 전달하는 스레드를 시작한다. 여기서는 for 루프에서 생성 된 클래스를 만들고 처리해야하는 행은 생성자에서 전달됩니다. 그런 다음 객체에서 행을 처리하기 위해 스레드를 시작하는 Start 메소드를 가져야합니다.

으로 보일 것 같은 클래스의 개요는 다음과 같습니다

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. 
    } 
} 

도움이 되었기를 바랍니다.

+0

후에 스레드 수를 결정하고 스레드 당 행 수를 계산하십시오. 나는이 for 루프를 가지고있다. (int threadNum = 0; threadNum = threadCount; threadNum ++) { List cells = new List (); cells.AddRange(); } 내가 이해할 수없는 것은 어떻게하면 1에서 2000까지 실행될 루프를 처음으로 확인하고 2001 년부터 다시 실행할지 두 번째로 확인하는 것입니다. – harpermartin

0

죄송합니다. 아직 답변을 드리지 못해 죄송 합니다만, 아직 Jaco에 게시 할 수있는 평판은 없습니다.

어쨌든 일반적으로 작업 부하/버킷 크기에 따라 스레드 수를 결정하고 싶지는 않습니다. CPU 코어 수에 따라 버킷 크기를 결정하는 것이 좋습니다. 이것은 스레드 전환을 막기 위해서이며 또한 OS/바이러스 스캐너의 한 코어가 도움을 줄 수 있습니다.

는 ... 스레드/코어/공정 카운트 얻을이 게시물 보려면 : 그래서 다시 질문에 대한 스레드하는 방법에 대한 How to find the Number of CPU Cores via .NET/C#?

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); 
} 
관련 문제