2012-09-24 4 views
3

나는 다음과 같은 코드를 가지고 :변수 backgroundWorker 매개 변수는 항상 동일합니까?

내 목표는
// 1. 
     public void RunSQL(QuerySetup querySetup) 
     { 
      //querySetup.Users is 10 
      for (int i = 1; i <= querySetup.Users; i++) 
      { 
       querySetup.CurrentUser = i; 
       var worker = new BackgroundWorker {WorkerReportsProgress = true}; 
       worker.DoWork += worker_DoWork; 
       worker.RunWorkerCompleted += worker_RunWorkerCompleted; 
       worker.RunWorkerAsync(querySetup); 
      } 
     } 


    // 2. 
    void worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     var querySetup = e.Argument as QuerySetup; 
     // Doing stuff... 
     e.Result = querySetup.CurrentUser; 
    } 

    // 3. 
    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     Console.WriteLine("User " + e.Result.ToString() + " is done."); 
    } 

는, 그 말에 나는 얻을 :

사용자 1은 사용자 2가

...

을 수행

완료

사용자 10이 완료되었습니다.

(해당 부분에 없음 소액 주문)

하지만 "사용자 10이 완료되었습니다"는 10 배 밖에되지 않습니다.

하지만 왜? 어떻게 든 내 작업자 프로세스를 표시해야하므로 나중에 확인할 수 있습니다.

+1

모든 작업자에게 동일한 querySetup 객체를 전달하고 있음을 의미합니다. –

+0

네, @ JoãoAngelo가 말했습니다. –

답변

4

예, 여기서 querySetup 객체는 하나 뿐이며 기본 루프는 현재 사용자를 계속 변경합니다.
모든 스레드가 단일 개체를 공유합니다.

for (int i = 1; i <= querySetup.Users; i++) 
{ 
    querySetup.CurrentUser = i; 
    ... 
    worker.RunWorkerAsync(querySetup); 
} 

기본 솔루션 (다른 querySetup 구성원 필요하지 않은 경우는)

for (int i = 1; i <= querySetup.Users; i++) 
{ 
    //querySetup.CurrentUser = i; 
    ... 
    worker.RunWorkerAsync(i); 
} 
+0

오 물론 ... 물론. 나는 다른 회원들을 필요로하지만, 이제 나는 그 요지를 얻는다. 감사. – Feroc

2

QuerySetup 하나의 인스턴스 만 있습니다.

현재 사용자를이 인스턴스에 저장합니다. 따라서 현재 사용자는 항상 루프의 마지막 사용자가됩니다.

1

루프가 완료된 후 모든 작업자가 완료하면 모두 동일한 글로벌 상태 querySetup.CurrentUser이 표시되며 그 순간은 10입니다.

멀티 스레드를 사용하는 가장 좋은 방법은 스레드간에 상태를 공유하는 것이 아니라 각 스레드 함수에 자체 데이터 복사본을 제공하는 것입니다. 이 경우 스레드 기능에 대한 데이터로 querySetup을 제공하는 대신 querySetup.CurrentUser

관련 문제