2013-10-14 7 views
0

네트워크를 통한 연결 프로세스를 실행하는 데 복수 backgroundworker을 사용하고 있습니다. datagridview에있는 행 수를 기반으로 각 행 값을 페치하고 긴 프로세스를 수행하는 다른 클래스 메소드를 통과합니다. 여기서 backgroundworker를 시작하기 위해 루프를 사용하고 있습니다. 문제는 프로세스가 시작될 때 datagridview 행 수를 기반으로 더 많은 backgroundworkers가 실행되기 시작하는 것입니다. 그러나 나는 이것을 제한하고 싶다. 예를 들어 50 행이 있다면 한 번에 5 명의 백그라운드 워커를 실행하려고합니다. 5 명이 끝나면 다음 5 일이 시작됩니다. 어떻게 제한하는거야?실행할 백그라운드 워커의 수를 제한합니다.

Backgroundworker bs; 
private void button1_Click(object sender, EventArgs e) 
{ 
    threadNumber = 0; 
    threadRunning = 0; 
    for(int i=0;i<datagridview1.Rows.Count;i++) 
    { 
     bs = new Backgroundworker(); 
     bs.DoWork += new DoWorkEventHandler(bs_DoWork); 
     bs.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bs_Completed); 
     bs.WorkerSupportCancellation = true; 
     bs.RunWorkerAsync(i); 
    } 
} 

private void bs_DoWork(object sender, DoWorkEventArgs e) 
    { 
    int i = (int)e.Argument; 
    while(bs.CancellationPending !=true && threadNumber < datagridview1.Rows.Count) 
    { 
     lock (this) 
     { 
      for (int i = 0; i < Max_Threads - threadRunning; i++) 
      { 
       if (threadNumber < datagridview1.Rows.Count) 
       { 
        Webmethod obj = new webmethod(); 
        obj.Callmethod(i); // this takes long time to perform 
        threadNumber +=1; 
        threadRunning +=1; 
       } 
       } 
      } 
} 
} 

을하지만 난이 시점에서 프로세스를 시작할 때 모든 backgroundworkers는 작업을 시작합니다

나는 다음 코드를 사용하고 있습니다. 누구든지이 일에서 나를 도울 수 있습니까? 사전에

감사합니다 ..

답변

2

당신이 할하려는 것은 완전히 명확하지 않다. 클릭 메서드는 각 데이터 행에 대해 BackgroundWorker을 새로 시작하지만 DoWork 핸들러는 각 행에 대해 내부 루프를 실행합니다. 매우 혼란 스럽습니다. I 당신이 원하는 것은 Max_Threads 근로자를 시작하고 그들이 행 처리에 협조하도록하는 것입니다.

threadNumber을 증가시키는 데 문제가 있습니다. Increment는 원자 적 연산이 아니므로 동시 증가하는 두 개의 스레드가 서로 스테핑 할 가능성이 있습니다. 아마도 Interlocked.Increment을 사용하여 액세스 권한을 동기화해야합니다. 코드, 그 작업 선을 위해

int threadNumber; 
private void button1_Click(object sender, EventArgs e) 
{ 
    threadNumber = -1; 
    // Start Max_Threads workers 
    for(int i=0; i<Max_Threads; i++) 
    { 
     var bs = new Backgroundworker(); 
     bs.DoWork += new DoWorkEventHandler(bs_DoWork); 
     bs.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bs_Completed); 
     bs.WorkerSupportCancellation = true; 
     bs.RunWorkerAsync(); 
    } 
} 

private void bs_DoWork(object sender, DoWorkEventArgs e) 
{ 
    // Process items until cancellation requested, or until end of list 
    while(!bs.CancellationPending) 
    { 
     int rowNumber = Interlocked.Increment(ref threadNumber); 
     if (rowNumber >= datagridview1.Rows.Count) 
     { 
      break; 
     } 
     Webmethod obj = new webmethod(); 
     obj.Callmethod(rowNumber); // this takes long time to perform 
    } 
} 
+0

감사 :

나는 당신이하고 싶은 것은이라고 생각합니다. 하지만 나는 의심의 여지가있다. callmethod에서 everProcess를 위해 datagridview에 상태 메시지를 보내고 있지만, 그게 나타나지 않는다. 왜 그런 일이 일어 났는지 말해 줄 수 있니? – yasmuru

관련 문제