2013-07-12 2 views
0

필자에게는 concurrentbag의 한 독자와 여러 독자가 있습니다.concurentbag를 다시 초기화하는 것이 안전합니까?

writer는 정기적으로 데이터베이스에서 concurrentbag의 전체 내용을 새로 고칩니다.

작가 스레드 내에서 다시 초기화하는 것이 안전합니까 (예 : = 새로운 concurrentbag)? 그렇지 않은 경우 모든 읽기 및 쓰기 중에 잠글 수있는 유일한 옵션이 있는데 이는 오히려이 점을 무시합니다. 나는 가방에 대해 한 번에 한 장씩 비울 수 없다. 왜냐하면 어떤 배설물을 읽다가 그 과정이 부분적 정보에 기반을 두게 될 것이기 때문이다.

감사합니다.

+1

무엇이 당신의 걱정입니까? 일부 독자 스레드가'ConcurrentBag <>'의 한 인스턴스에서 읽기 작업을 시작한 다음 다른 인스턴스에서 동일한 읽기를 완료 할 수 있습니까? 아니면 스레드가 새 참조를 선택하지 않을까 두려워합니까? 어쩌면 당신은 '휘발성 (volatile)'필드를 원할 것입니다. –

+0

답장을 보내 주셔서 감사합니다. Jeppe. 내 우려는 읽기 중에 재 초기화가 발생하고 예외가 발생한다는 것입니다. –

+0

참조를 업데이트 할 때 .NET에서 원 자성입니다. 그 결과는 당연히 무작위입니다. 오래된 가방에서 얼마나 많은 물체가 소비되는지 정확히 예측할 수 없습니다. 그것이 받아 들일 수있는 행동이 될 수있는 방법을보기는 매우 어렵습니다. –

답변

1

우선, 이것은 ConcurrentBag 유형과 관련이 없습니다. 이것만으로도 완전히 안전 할 것입니다. 다른 스레드에서 동시에이 할 동안 하나 개의 스레드에서 메서드 호출이, 가방에서 수행되는 경우

:

_BagField = new ConcurrentBag<string>(); 

그런 다음 첫 번째 스레드에서 메서드 호출이 잘 완료, 그러나 이전 인스턴스의 입니다.

그러나 안전하지 않습니다,하지만 때문에 처음부터 유형을 사용하는 이유에, 결코 없었다 :

if (_BagField.Any()) 
    var percentage = 100/_BagField.Count(); // broken 

이 하나 개의 인스턴스에 .Any()를 호출 할 수 있으며 .Count()에 또 다른, 그러나 당신이 Any를 호출 한 직후 Count가 0으로 떨어지지 않도록하는 안전 장치가 없기 때문에 이것은 결코 안전한 적이 없습니다.

그러나 다른 스레드가 즉시 새 인스턴스를 선택한다는 보장은 없습니다. 예를 들어

이 :

string temp; 
while (!_Bag.TryTake(out temp)) 
{ 
    // process temp 
} 

새로운 인스턴스에 결코 수도 그냥 죽은 중지하기 전에 이전 가방 인스턴스를 처리하는 것입니다.

가방 수령을 포함하는 입력란이 volatile인지 확인하십시오.

+0

Lasse 감사합니다. 그래서, 필자는 concurrentbag를 휘발성으로 만들었고, 독서 스레드 내에서 ToList와 같은 복사본을 수행 한 다음 해당 복사본을 조작하면 작성자 전후의 전체 데이터 세트가 보장됩니다. 스레드가 다시 초기화했습니다. 옳은? –

+0

그렇습니다. 인스턴스 대체와 관련해서는 정확 합니다만,'ToList'와'ConcurrentBag'가 어떻게 작동하는지 모르기 때문에'ToList'가 스레드로부터 안전하다는 것을 보장하고 싶지는 않을 것입니다. 전체 인스턴스를 대체하는 것에 관한 것이지만, 다른 스레드가 동시에 백을 수정하는지 여부를 처리 할 것인지 여부를 지정합니다. –

+0

Super duper. 고맙습니다! –

관련 문제