지우는 방법 ConcurrentBag
? Clear
또는 같은 방법이 없습니다 RemoveAll
...
답변:
잠재적 인 경쟁 조건으로 인해 완전히 명확하지 않을 수도 있지만 다음으로 충분합니다.
while (!myBag.IsEmpty)
{
myBag.TryTake(out T _);
}
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
자체에 들어간 성능 조정을 무효화 할 수 있습니다 .
이 시점에서 다른 사람이 가방에 접근 할 수 없다는 것을 알고 있다면 날개를 달고기도하고 잠그지 마십시오. :-)
bag = new
아닐까요?
Interlocked.Exchange
잠금보다 더있을 수 있습니다
Interlocked.Exchange
교환시 다른 스레드가 가방에 추가되면 어떻게 작동합니까? 그 Add
동안 잠겨 Exchange
있습니까?
Interlocked.Exchange
여기서 중복됩니다 (스레드 안전성을 제공하지 않음).
선택한 답변은 일종의 해결 방법이므로 자체 해결 방법을 추가하고 있습니다.
내 솔루션은 System.Collections.Concurrent 네임 스페이스 에서 사용 가능한 모든 컬렉션을 확인하여 컬렉션에서 모든 요소를 지우는 것이 사소한 곳을 찾는 것이 었습니다.
ConcurrentStack의 클래스가 가지고 클리어 () 컬렉션의 모든 요소를 제거하는 방법. 사실, 네임 스페이스의 유일한 컬렉션입니다 (현재). 예, Push(T element)
대신 해야 Add(T element)
하지만 솔직히 시간을 절약 할 가치가 있습니다.
ConcurrentBag
있습니까? 이를 수행하는 기본 속성이나 방법을 볼 수 없습니다. 는 Contains
계산하지 않습니다. 제네릭 IEnumerable
의 확장 메서드이며 효율적이지 않습니다.
.NET 코어 2.0으로 / .NET 표준 2.1 / .NET 프레임 워크 5.0은 거기 Clear()
에 방법 ConcurrentBag<T>
. 참조 : ConcurrentBag.Clear .