2011-11-06 3 views
2

스레드 목록에서 다른 값으로 클래스를 실행하려고합니다. 예 :스레드 입력 매개 변수

 int index = 0; 
    foreach (TreeNode nd in tvew.Nodes[0].Nodes) 
    { 
     threadping[index] = new Thread(delegate() 
     { this.Invoke(new DelegateClientState(InvokeCheckNetworkState), new object[] {nd}); }); 

     threadping[index].Name = nd.Name; 
     threadping[index].IsBackground = true; 
     threadping[index].Start(); 

     index++; 
    } 

하지만 코드를 디버깅 할 때 클래스 매개 변수가 마지막 값이라는 것을 알 수 있습니다. 내가 스레드 클래스를 통해 갈 때마다 클래스가 입력 매개 변수의 값을 실행할 때마다 마지막 스레드의 마지막 값이라는 것을 의미합니다.

아무도 말해 줄 수 있습니까?

+0

threadPing 컬렉션을 초기화 한 코드를 표시 할 수 있습니까? 그리고 "클래스 매개 변수"또는 디버깅중인 스레드 클래스는 무엇입니까? –

답변

5

nd 변수가 클로저에 캡처 되었기 때문입니다. 스레드가 실행되면 이들은 모두 동일한 TreeNode 인스턴스, 즉 nd에 할당 된 마지막 인스턴스를 참조합니다. 해결하려면 범위 내에서 변경되지 않는 별도의 변수를 사용

foreach (TreeNode nd in tvew.Nodes[0].Nodes) 
{ 
    var current = nd; 
    threadping[index] = new Thread(delegate() 
    { this.Invoke(new DelegateClientState(InvokeCheckNetworkState), new object[] {current}); }); 

우리가 컴파일러 기술 얻을 경우, 컴파일러에 대한 읽을 수 있도록하기 위해 루프 변수를 포함하는 익명 클래스를 생성하기 때문에이 문제가 발생합니다 thread delegate 이것은 예상되는 동작입니다. 처음에는 처음 실행했을 때와 직관적으로 어긋납니다.

클로저 및 변수 캡처에 대한 자세한 설명은 see the Captured Variables section here (bottom section) in a Jon Skeet article 또는 this article from Eric Lippert입니다. 이것은 일반적으로 "수정 된 클로저에 대한 액세스"버그로 알려져 있습니다. StackOverflow 또는 Google에서 검색어를 검색하면 많은 조회가 발생합니다.

+0

tnx, 작동합니다. 또 다른 질문 : 내 스레드가 동시에 작동하지 않는 이유는 무엇입니까? 나는 첫 번째 루프가 끝날 때 발생하는 "InvokeCheckNetworkState"의 첫 번째 줄에서 중단 점을 가리 킵니다. 스레드가 이전 스레드 종료를 기다리는 것과 같습니다. 나는 네가 동시에 일하지 않는다는 것을 의미한다. 어떻게해야합니까? –

관련 문제