2010-08-05 2 views
2

그래서 Dictionary of List <myObj>을 얻은 다음 사전의 키를 순환하고 각 목록 <myObj>을 별도의 스레드에 전달하는 메서드가 있습니다.C# 스레드 실행 중 스레드 매개 변수가 변경됩니다 - 이유는 무엇입니까?

public static void ProcessEntries() { 

    Dictionary<string, List<myObj>> myDictionary = GetDictionary(); 

    foreach(string key in myDictionary.keys) 
    { 

     List<myObj> myList = myDictionary[key]; 

     Thread myThread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate() { 

      ProcessList(myList); 

     }  
    } 
} 

public static void ProcessList(List<myObj> myList) { 

    // Process entries 
    // read-only operations on myList 

} 

문제는 PROCESSLIST의 실행 중에 myList에 매개 변수가 단순히 변화이다 : 여기

몇 가지 코드/사이비 - 코드입니다.

스레드를 걷어차 기 전에 목록을 반복 한 다음 즉시 스레드 내부로 돌아 왔고 그 결과가 다른 것으로 나타났습니다.

나는 Dictionary 변수를 전역 변수로 만들어 문제를 해결했다. 가능한 수정 목록에서 [ThreadStatic] 속성을 사용하면됩니다.

정말로 알고 싶은 것은 아마도 myList 객체가 ProcessEntries()에서 다시 할당 될 때 myList 객체가 ProcessList() 내부에서 변경되는 이유일까요? 이것들은 두 개의 서로 다른 목록이 아닌가? 기본적으로 모든 매개 변수 전달이 값을 기준으로하는 경우 ProcessList() 함수에 myList의 로컬 복사본이없는 이유는 무엇입니까? (수행합니까?)

매개 변수를 스레드로 전달하고 실행 중에 상위 스레드 나 다른 스레드가 매개 변수를 변경하지 않도록 지정하는 방법이 있습니까? (이것은 전역 변수의 [ThreadSafe] 속성과 비슷합니다.)

+1

코드/psuedocode가 정확하고 완전합니까? 내가 볼 수있는 것부터, 무슨 일이 일어나는가에 대한 가정은 틀린 반면 코드가 정상적으로 작동해야하는 것처럼 보입니다. –

답변

0

참조을이 값으로 전달하므로,이 값을 다른 값으로 수정하면 모든 값이 달라집니다.

2

귀하의 의사 코드가 실제로 귀하의 실제 코드를 정확하게 반영한 것으로 의심됩니다. 나는 당신의 실제 코드는 다음과 같습니다 의심 : 그런 경우에는

foreach(var pair in myDictionary) 
{ 
    Thread myThread = new Thread(delegate() { 
     ProcessList(pair.Value); 
    }); 
    myThread.Start(); 
} 

, 문제가 pair 변수가 포착되고 있다는 점이다

- 그래서 당신의 스레드가 시작하는 시간, 그것은 다른 키를 참조 할 수있다/값 쌍.

를 해결하는 방법은 더 의사 코드처럼 정확하게 코드를 확인하는 것입니다 :

foreach(var pair in myDictionary) 
{ 
    // You'll get a new list variable on each iteration 
    var list = pair.Value; 
    Thread myThread = new Thread(delegate() { 
     ProcessList(list); 
    }); 
    myThread.Start(); 
} 

자세한 내용은 Eric Lippert's blog post on this를 참조하십시오.

이것이 잘못된 것이 아니라면 의사 코드가 아닌 실제을 입력하십시오. short but complete example demonstrating the problem이 이상적입니다.

1

또한 다른 스레드가 사용하려고하는 스레드에 영향을주지 않도록하십시오. 자물쇠와 모니터를 사용해야합니다. 불과 몇 주 전에 몇 가지 문제가있었습니다.