2013-09-05 3 views
0

I가 큰 데이터 세트를 반복하는 방법을 가지고 직렬화 소비자 스레드에 처리 결과를 반환. 스트리밍 PLinq는 최상의 성능을 발휘합니다. PLINQ와 물체 풀링하여 ConcurrentCollections

이러한 작업은 빈번

때문에, 전 오브젝트 생성을 최소화하기 위해, 제 처리 용기를 캐시하는 objectpool를 사용하고있다. 나는 concurrentspack (concurrentbag 및 concurrentqueue 같은 문제를 전시)를 사용하여 objectpool 구현을 시도했다. 드문 경우지만 동일한 항목 (해시 코드 참조)은 소비자 스레드가 풀지는 않았지만 동일한 스레드에 의해 풀에서 가져옵니다. 나는 풀의 취득 및 해제 방법에서 추적을 첨가하고,이 출력입니다 :

5 : 11 : 11 : 32.250 PM은 스레드 (31)
5 항목 16071020 받기 32.254 오후 스레드 (31)
에 대한 항목 16071020 받기 5 : 11 : 11 :
5 실 27 32.260 오후에 담기 항목 16,071,020 프로세스 방법에서

var itemsToProcess = data.AsParallel() 
         .Where(x => Filter(x)) 
         .Select(row => Process(row)); 

: 여기

스레드 27 32.286 오후에 담기 항목 16,071,020는 내가 사용하고 코드입니다 , 나는 물건을 이리 앞으로 가져올 것이다.

result = ObjectPool.Instance.GetObject(); 

풀 클래스 구현 :

public class ObjectPool 
{ 
    private ConcurrentStack<object[]> _objects; 
    private int size; 
    private const int maxSize = 20000; 

    private static ObjectPool instance = new ObjectPool(500); 
    public static ObjectPool Instance 
    { 
     get { return instance; } 
    } 

    private ObjectPool(int size) 
    { 
     this.size = size; 
     _objects = new ConcurrentStack<object[]>(); 
    } 

    public object[] GetObject() 
    { 
     object[] item; 
     if (_objects.TryPop(out item)) 
     { 
      Trace.WriteLine(string.Format("Get item {0} for Thread {1}", item.GetHashCode(), Thread.CurrentThread.ManagedThreadId)); 
      return item; 
     } 
     return new object[size]; 
    } 

    public void Clear() 
    { 
     _objects.Clear(); 
    } 

    public void PutObject(object[] item) 
    { 
     Trace.WriteLine(string.Format("Put item {0} for Thread {1}", item.GetHashCode(), Thread.CurrentThread.ManagedThreadId)); 

     if (_objects.Count < maxSize) 
     { 
      _objects.Push(item); 
     } 
    } 
} 

I가 발생하는 이런 상황을 방지하는 방법에 딱하다 풀을 해요. 이것이 일어날 수있는 이유와 그것을 방지하는 방법에 대한 아이디어가 있습니까?

+0

'인스턴스'구현 방법을 보여줄 수 있습니까? –

+0

@SimonWhitehead 의견을 보내 주셔서 감사합니다. 나는 원래 게시물에서 싱글 톤 구현을 생략했다. 케이스와 관련이 없기 때문에, 물건을 더 명확하게 만든다. – anchandra

+0

실수로 같은 배열에'PutObject()'를 두 번 호출하지 않겠습니까? – svick

답변

1

게시 한 코드에 아무런 이상이 보이지 않습니다. 나에게

는 대부분의 경우는 같은 배열에 두 번 PutObject()를 부르는 것 같다. 그러나 더 많은 코드를 보지 않고도 말할 수는 없습니다.