2013-02-20 4 views
0

나는이 유사한 작업을 수행하는 백그라운드 스레드가 있습니다.회원 수집 반복 스레드 안전

foreach으로 알 수 있습니다. 반복 중에 UpdateServers이 호출되면 반복기가 이전 인스턴스에 속하기 때문에 반복이 스레드로부터 안전합니다. for 루프와

은 반복으로 안전 할 수 있습니다

var serverList = client.Servers; 
for (int x = 0 ; x < serverList.Count ; ++x) 
{ 
    DoSomething(serverList[ x ]); 
    // ... 
} 

그러나 컴파일러가 생성 보장 (또는 생성을 강제 할 수있는 방법이 있다면 제가 궁금하네요 것은, 만약 소비자가 다음과 같이 반복하기로 결정한 경우 위의 코드를 참조하십시오.

for (int x = 0 ; x < client.Servers.Count ; ++x) 
+1

서버 변수에 대한 액세스 권한을 부여하지 말고 대신 클로저를 받고 반복 자체를 수행하는 메소드가 있거나 서버 이름을 적절히 지정하여 호출하고 저장해야한다는 것을 분명히하는 메소드가 있어야합니다. 반복적으로 사용하는 것이 아니라 변수로 변환합니다. – entonio

답변

2

컴파일러가 지시하는 코드를 생성합니다. 필드의 값을 반복해서로드하는 것을 피하기 위해 최적화가있을 수 있지만 실제로는 그 필드에 의존해서는 안됩니다.

그래서 컴파일러에서 코드를 생성 할 수는 있지만 그렇게 할 필요는 없으므로 코드를 작성하지 않아도되도록 코드를 작성해야합니다.

또한 매우 까다로울 수 있습니다 (예 : volatile). 가장 좋은 방법은 실제 성능 문제가 발생하지 않는 한 일반적으로 잠금을 사용하는 것입니다 (거의 발생하지 않음).

+0

우리는 존재하지 않는 성과에 대한 우려로 살고 있습니다. 이런 종류의 문제는 어렵습니다. 공연 전의 정확함. +1 – spender

1

서로 잠그지 않아도된다면 실용적 일 수 있습니다. 그것은 메모리 사용 및 개체 생성 측면에서 조금 무거울 것입니다. 아마 더 깨끗한 방법이있을거야.

private ReadOnlyCollection<IPAddress> _servers; 
public ReadOnlyCollection<IPAddress> Servers { 
    get { 
     lock(_servers) { 
      return new ReadOnlyCollection<IPAddress>(_servers); 
     } 
    } 

    private set { 
     lock(_servers) { 
      _servers = value; 
     } 
    } 
} 
+0

또 다른'ReadOnlyCollection'을 감싸는'ReadOnlyCollection'을 만들 이유가 없습니다. 그냥 오버 헤드가 추가됩니다. – svick

+0

나는 많은 것을 알았다. 계속해서 최적화하여 최적화하십시오. 그 특별한 물건에 대한 나의 지식은 꽤 제한적이며 자물쇠 안에서 돌아 오는 것은 무의미한 것처럼 보였다. 여기에서 목표는 호출자에게 반복되는 동안 잠금을 유지하는 대신 액세스 할 때 호출자에게 줄 것을 제공하는 것이 었습니다. 그것은 메모리 대 잠금 성능 질문 인 것 같습니다. – Syddraf

0

사람이 위의 제안대로 잠금을 사용해야하지만, 당신은 또한 잠금이 것을 다음 반복하는을 통해 목록에 대한 참조를 반복하는 대신 .ToArray를 사용하지 않음으로써 개최되는 시간을 최소화 할 수 있습니다 .

+0

Syddraf의 대답에는 자물쇠를 들고있는 동안 반복이 없습니다. – svick

+0

은 합의했지만 op 상태가 for 루프 인 것처럼 해당 메소드를 결합합니다 –

+0

내 관심사는 소비자가 우리 문서를 따르지 않을 수 있다는 것입니다. 나는 암시 적으로 thread-safe 한 디자인을 찾고 있었는데, 소비자가 반복을 안전하게하기 위해 농구를 뛰어 넘지 않아도되었다. –