Programing

ConcurrentBag에서 모든 항목을 제거하는 방법은 무엇입니까?

lottogame 2020. 11. 8. 09:11
반응형

ConcurrentBag에서 모든 항목을 제거하는 방법은 무엇입니까?


지우는 방법 ConcurrentBag? Clear또는 같은 방법이 없습니다 RemoveAll...


T someItem;
while (!myBag.IsEmpty) 
{
   myBag.TryTake(out someItem);
}

2017 년 10 월 3 일 업데이트 : @Lou가 올바르게 지적했듯이 할당은 원자 적입니다. 이때, 생성은 ConcurrentBag원자되지 않지만 그 변수에 대한 참조를 퍼팅 것이다 원자 수 - 그래서 잠금 또는 Interlocked.Exchange주위가 반드시 필요한 것은 아니다.

더 읽을 거리 :

참조 할당은 원자 적이므로 Interlocked.Exchange (ref Object, Object)가 필요한 이유는 무엇입니까?

참조 할당은 스레드 세이프입니까?


언제든지 가방 자체에 대한 액세스를 잠그고 새 인스턴스를 만들 수 있습니다. 가방에 들어있는 항목은 다른 항목이 없으면 GC 대상이됩니다.

lock (something)
{
    bag = new ConcurrentBag();
}

또는 Lukazoid가 지적한대로 :

var newBag = new ConcurrentBag();
Interlocked.Exchange<ConcurrentBag>(ref bag, newBag);

그러나 컨텐츠를 비닝하는 쉬운 방법은 항목이 액세스를 원할 때마다 잠금을 얻는다고 가정합니다. 이것은 비용이 많이 들고 ConcurrentBag자체에 들어간 성능 튜닝을 무효화 할 수 있습니다 .

이 시간에 다른 사람이 가방에 접근 할 수 없다는 것을 알고 있다면 날개를 달고기도하고 잠그지 마십시오. :-)


선택한 답변은 일종의 해결 방법이므로 자체 해결 방법을 추가하고 있습니다.

내 솔루션은 System.Collections.Concurrent 네임 스페이스 에서 사용 가능한 모든 컬렉션을 살펴보고 컬렉션에서 모든 요소를 ​​지우는 것이 쉬운 곳을 찾는 것이 었습니다.

ConcurrentStack의 클래스가 가지고 클리어 () 컬렉션의 모든 요소를 제거하는 방법. 사실, 그것은 (현재) 네임 스페이스의 유일한 컬렉션입니다. 예, Push(T element)대신 해야 Add(T element)하지만 솔직히 시간을 절약 할 가치가 있습니다.


루프에서 객체를 하나씩 제거 할 수 있습니다.

object result;
while (bag.TryTake(out result));

루프가 완료된 후 다른 스레드에 의해 다음 문 앞에 항목이 추가 될 수 있기 때문에 bag이이 루프 이후에 비어 있다고 보장되지 않습니다.


해결 방법의 정신으로 .. ConcurrentDictionary<T, bool>원자 지우기가 있지만 키가 있는지 신속하게 확인할 수 있습니다. 'Quickly'는 물론 상대적인 용어이지만 사용량에 따라 큰 스택을 열거하는 것보다 빠를 수 있습니다.

참고 URL : https://stackoverflow.com/questions/5377296/how-to-remove-all-items-from-concurrentbag

반응형