네트워크를 통해 원격 사이트에 연결하고 일반 목록을 반환하는 여러 기능을 실행하려고합니다. 하지만 동시에 실행하고 싶습니다.
예를 들면 :
public static List<SearchResult> Search(string title)
{
//Initialize a new temp list to hold all search results
List<SearchResult> results = new List<SearchResult>();
//Loop all providers simultaneously
Parallel.ForEach(Providers, currentProvider =>
{
List<SearchResult> tmpResults = currentProvider.SearchTitle((title));
//Add results from current provider
results.AddRange(tmpResults);
});
//Return all combined results
return results;
}
내가보기에 ‘결과’에 대한 여러 삽입이 동시에 발생할 수 있습니다. 이로 인해 애플리케이션이 중단 될 수 있습니다.
이것을 어떻게 피할 수 있습니까?
답변
//In the class scope:
Object lockMe = new Object();
//In the function
lock (lockMe)
{
results.AddRange(tmpResults);
}
기본적으로 잠금은 하나의 스레드 만 해당 중요 섹션에 동시에 액세스 할 수 있음을 의미합니다.
답변
동시 컬렉션을 사용할 수 있습니다 .
System.Collections.Concurrent
네임 스페이스에서 해당 유형의 장소에서 사용되어야합니다 여러 스레드 안전 컬렉션 클래스 제공System.Collections
및System.Collections.Generic
복수의 thread가 동시에 컬렉션에 액세스 할 때마다 네임 스페이스를.
예를 들어 ConcurrentBag
항목이 추가 될 순서를 보장 할 수 없기 때문에 사용할 수 있습니다.
스레드로부터 안전하고 순서가 지정되지 않은 개체 컬렉션을 나타냅니다.
답변
코드를 선호하는 사람들을 위해 :
public static ConcurrentBag<SearchResult> Search(string title)
{
var results = new ConcurrentBag<SearchResult>();
Parallel.ForEach(Providers, currentProvider =>
{
results.Add(currentProvider.SearchTitle((title)));
});
return results;
}
답변
동시 컬렉션은 .Net 4의 새로운 기능입니다. 새로운 병렬 기능과 함께 작동하도록 설계되었습니다.
.NET Framework 4의 동시 컬렉션을 참조하세요 .
.NET 4 이전에는 여러 스레드가 단일 공유 컬렉션에 액세스 할 수있는 경우 고유 한 동기화 메커니즘을 제공해야했습니다. 컬렉션을 잠 가야했습니다 …
… System.Collections.Concurrent의 [새로운] 클래스와 인터페이스 [.NET 4에 추가됨]는 스레드 간의 공유 데이터와 관련된 […] 다중 스레드 프로그래밍 문제에 대한 일관된 구현을 제공합니다.
답변
이것은 PLINQ AsParallel
와 SelectMany
다음을 사용하여 간결하게 표현할 수 있습니다 .
public static List<SearchResult> Search(string title)
{
return Providers.AsParallel()
.SelectMany(p => p.SearchTitle(title))
.ToList();
}