목록 대신 Blocking Collection을 사용할 때와 Concurrent Bag을 사용할 때
"왜 이 병렬이 이루어지는가?"라는 질문에 대한 승인된 답변입니다.For Each code freeze up?」(각 코드 freeze up?)은 WPF 어플리케이션에서 List usage by ConcurrentBag로 대체하도록 권장합니다.
이 경우 Blocking Collection을 대신 사용할 수 있는지 알고 싶습니다.
이 은 쓸 수 .BlockingCollection
하지만 그렇게 하는 것은 전혀 의미가 없다.
먼저 이 패키지는 를 구현하는 컬렉션의 래퍼입니다.이러한 인터페이스를 구현하는 모든 유형을 기본 스토리지로 사용할 수 있습니다.
를 작성하는
BlockingCollection<T>
오브젝트에서는 제한 용량뿐만 아니라 사용할 컬렉션 유형도 지정할 수 있습니다.를 들어, 이렇게 하다를 할 수 .ConcurrentQueue<T>
in, 동작 또는 in, first out(FIFO; First out) 동작을ConcurrentStack<T>
in,out( 동작의 객체. in, out(LIFO) 동작를 클래스는 모두 할 수 .IProducerConsumerCollection<T>
인터페이스입니다.「」의 디폴트 은, 과 같습니다.BlockingCollection<T>
ConcurrentQueue<T>
.
여기에는 다음이 포함됩니다.ConcurrentBag<T>
백.백.백.백.백.백.백.백.백.백.백.백.백.백.백.백.백.백.백.백.백.백.백.백.백.백 차단.백.백.백.백. IProducerConsumerCollection<T>
단컬 ??『 』의 BlockingCollection
내 것이 아니다) 라고 말한다 것이 아니다)
BlockingCollection<T>
의 랩퍼로 사용됩니다.IProducerConsumerCollection<T>
instance: 데이터를 삭제할 수 있을 때까지 컬렉션에서 삭제 시도를 차단할 수 있습니다.마찬가지로 a.BlockingCollection<T>
에서 허가된 데이터 요소의 수에 상한을 적용하기 위해 작성할 수 있습니다.IProducerConsumerCollection<T>
[...]
에서는 둘 할 가 없기 에 '도 할 가 없다'를합니다.BlockingCollection
는 사용되지 않는 기능 계층을 추가합니다.
List<T>
는 싱글 스레드애플리케이션에서 사용하도록 설계된 컬렉션입니다.ConcurrentBag<T>
입니다.Collections.Concurrent
멀티스레드 환경에서 컬렉션 사용을 단순화할 수 있도록 설계된 네임스페이스입니다.Concurrent Collection을 사용하는 경우 다른 스레드에 의한 손상을 방지하기 위해 컬렉션을 잠글 필요가 없습니다.특별한 잠금 코드를 작성할 필요 없이 컬렉션에서 데이터를 삽입하거나 가져올 수 있습니다.BlockingCollection<T>
는 스레드 간의 공유 컬렉션에서 새로운 데이터를 사용할 수 있는지 여부를 확인할 필요가 없도록 설계되어 있습니다.공유 컬렉션에 새로운 데이터가 삽입되면 컨슈머 스레드가 즉시 활성화됩니다.따라서 일반적으로 while loop에서 특정 시간 간격으로 사용자 스레드에 새 데이터를 사용할 수 있는지 확인할 필요가 없습니다.
세이프가 할 List<T>
「」, 「」, 「」도 .ConcurrentBag<T>
BlockingCollection<T>
최선의 선택이 될 겁니다두 컬렉션은 모두 생산자와 소비자의 시나리오를 지원하기 위해 특화되어 있으므로 컬렉션에서 아이템을 동시에 추가 및 삭제하는 스레드가 여러 개 없는 한 다른 옵션을 찾아야 합니다(대부분의 경우 최적의 후보가 됩니다).
특히 에 대해서는 생산자와 소비자가 혼합된 시나리오를 대상으로 한 매우 전문적인 클래스입니다.즉, 각 worker-thread는 생산자이면서 소비자(같은 컬렉션에서 항목을 추가 및 삭제하는 것)가 될 것으로 예상됩니다.클래스의 내부 스토리지에 적합한 후보가 될 수 있지만, 그 외에는 이 클래스에 유리한 사용 시나리오를 상상하기 어렵습니다.
' 하다'라고 합니다.ConcurrentBag<T>
입니다.List<T>
않다하지만 그렇지 않지.두 API의 유사성으로 인해 오해의 소지가 있습니다. " "Add
a까지List<T>
목록 끝에 항목을 추가할 때 결과가 표시됩니다.에의 콜ConcurrentBag<T>
대신 가방 내 임의의 슬롯에 아이템을 추가할 수 있습니다.ConcurrentBag<T>
기본적으로 순서가 없습니다.열거되도록 최적화되어 있지 않으며, 그렇게 하도록 명령받았을 때 작업이 제대로 수행되지 않습니다.내부적으로는 다수의 스레드 로컬 큐를 유지하므로 콘텐츠의 순서는 어떤 스레드가 언제 무슨 일이 일어났느냐가 아니라 어떤 스레드가 무엇을 했느냐에 따라 결정됩니다.의 각 열거 전에ConcurrentBag<T>
이러한 스레드 로컬큐는 모두 어레이에 복사되어 가비지 콜렉터(소스 코드)에 압력이 가중됩니다.예를 들어, 이 선은var item = bag.First();
하나의 요소만 반환하는 경우 전체 컬렉션의 복사본이 생성됩니다.
에 의해, 「」가 .ConcurrentBag<T>
결과를 저장하기 위한 이상적인 선택은 아니다Parallel.For
/Parallel.ForEach
loopsyslog.syslog..syslog.
나은 스레드 List<T>.Add
방법입니다."Enqueue"는 "Add"보다 덜 친숙한 단어이지만 실제로는 예상대로 작동합니다.
라고 하는 은 없다.ConcurrentBag<T>
수 있다ConcurrentQueue<T>
예를 들어 둘 다 컬렉션에서 특정 항목을 제거하는 방법을 제공하지 않습니다.를 사용한 동시 컬렉션을 원하는 경우TryRemove
가 있는 방법key
파라미터를 지정하면 클래스를 볼 수 있습니다.
그ConcurrentBag<T>
는 마이크로소프트 문서의 태스크 병렬 라이브러리 관련 예제에 자주 나타납니다.예를 들면 여기처럼요.누가 이 문서를 작성했든, 그들은 이 문서의 작은 사용 편의성 이점을 더 중요하게 여겼던 것 같습니다.Add
대신Enqueue
잘못된 수집을 사용했을 때의 동작/퍼포먼스상의 단점보다 큰 영향을 줍니다.이는 TPL이 처음 도입된 시기에 작성된 사례로, 병렬 프로그래밍에 익숙하지 않은 개발자들이 라이브러리를 신속하게 채택하는 것이 목표였다는 점을 고려하면 어느 정도 의미가 있습니다.난 알았어요,Enqueue
처음 봤을 때 무서운 단어예요.안타깝게도 현재 모든 세대의 개발자들이 이 기술을 통합하고 있습니다.ConcurrentBag<T>
이 컬렉션이 얼마나 특수한지 고려해 볼 때, 비록 그곳에 있는 것은 아니지만 그들의 정신적 도구에 있습니다.
루프의 결과를 소스 요소와 정확히 같은 순서로 수집하려면List<T>
에 의해 lock
대부분의 경우 오버헤드는 무시할 수 있습니다.특히 루프 내부의 작업이 엉성할 경우에는 더욱 그렇습니다.아래에 각 요소의 인덱스를 가져오는 LINQ 연산자의 예를 나타냅니다.
var indexedSource = source.Select((item, index) => (item, index));
List<TResult> results = new();
Parallel.ForEach(indexedSource, parallelOptions, entry =>
{
var (item, index) = entry;
TResult result = GetResult(item);
lock (results)
{
while (results.Count <= index) results.Add(default);
results[index] = result;
}
});
는요.source
을 사용하다이치 됩니다.TResult[]
어레이를 잠그지 않고 병렬로 업데이트합니다.
TResult[] results = new TResult[source.Count];
Parallel.For(0, source.Count, parallelOptions, i =>
{
results[i] = GetResult(source[i]);
});
에는 태스크 장벽이 되어 있기 의 모든 입니다.results
어레이는 현재 스레드(표준)에서 표시됩니다.
이렇게 하면 됩니다.BlockingCollection
그럴 수 있어요. finishedProxies
뭇매를 맞다
BlockingCollection<string> finishedProxies = new BlockingCollection<string>();
항목을 추가하려면 다음과 같이 입력합니다.
finishedProxies.Add(checkResult);
작업이 완료되면 콘텐츠에서 목록을 만들 수 있습니다.
언급URL : https://stackoverflow.com/questions/15400133/when-to-use-blockingcollection-and-when-concurrentbag-instead-of-listt
'programing' 카테고리의 다른 글
어떻게 git이 케이스 변경을 무시합니까? (0) | 2023.04.20 |
---|---|
CTE와 임시 테이블 중 어느 쪽이 더 퍼포먼스입니까? (0) | 2023.04.20 |
varchar(8000)보다 varchar(500)가 유리합니까? (0) | 2023.04.20 |
윈도우즈 배치 스크립트에서 날짜 및 시간 형식 지정 (0) | 2023.04.20 |
기존 테이블에서 테이블(구조)을 작성합니다. (0) | 2023.04.20 |