2017-09-29 4 views
1
public List<Order.RootObject> DoStuff() 
    { 
     List<Order.RootObject> cOrders = new List<Order.RootObject>(); 

     var client = new RestClient(url); 
     var request = new RestRequest("orders", Method.GET); 

     request.AddParameter("pgsize", "2000"); 
     request.AddParameter("pgnum", "1"); 

     var response = client.Execute<Order.RootObject>(request); 
     int iLoop = response.Data.TotalResults/2000 + 1; 
     Parallel.For(1, iLoop, 
      index => { 
       request.Parameters[“pgnum”].Value = index; 
       response = response = client.Execute<Order.RootObject>(request); 
       cOrders.Add(response.Data); 
      }); 
     return cOrders; 
    } 

cOrders는 API에서 되돌아 오는 모든 응답으로 끝나지 않습니다. 간단한 For 루프로 변경하면 모든 것이 좋지만 일부 호출의 경우 필요한 모든 데이터를 얻기 위해 API에 많은 루프가 있기 때문에 오래 걸립니다.ThreadSafe Parallel.For

+0

'RestClient'와'List'에 아래에 언급 된 스레드 안전성 문제 외에도 서버가 지원할 동시 연결 수를 확인하고'Parallel.For' 호출에서'MaxDegreeOfParallelism'을 제한해야합니다. –

답변

1

루프 내에서 요청 개체를 재사용하고 있습니다. 여러 스레드가이 단일 인스턴스를 액세스하고 수정하므로 작동하지 않습니다. 요청의 인스턴스에 대한 액세스를 동기화/잠금 (루프가없는 일반 루프가 있음)하거나 루프 내의 모든 요청에 ​​대해 자체 요청 객체를 만들어야합니다. ...

1

목록이 스레드가 아닙니다. 안전한. 프레임 워크의 대부분의 유형은 그렇지 않습니다. 다중 스레드 환경에서 하나를 사용할 때는 check the docs을 사용해야합니다.

이 형식의 공용 static (Visual Basic의 경우 Shared) 멤버는 스레드로부터 안전합니다. 모든 인스턴스 멤버가 스레드로부터 안전하다는 보장은 없습니다. List에서 여러 읽기 작업을 수행하는 것이 안전하지만 컬렉션을 읽는 동안 수정하면 문제가 발생할 수 있습니다. 스레드의 안전을 보장하려면 읽기 또는 쓰기 작업 중에 컬렉션을 잠급니다. 읽기 및 쓰기를 위해 여러 스레드가 콜렉션에 액세스 할 수있게하려면 사용자 고유의 동기화를 구현해야합니다. 기본 제공 동기화를 사용하는 컬렉션의 경우 System.Collections.Concurrent 네임 스페이스의 클래스를 참조하십시오. 본질적으로 스레드로부터 안전한 대안은 ImmutableList 클래스를 참조하십시오.

저는 불변의 컬렉션을 실제로 파고 대부분의 상황에서 동시 컬렉션보다 선호합니다. 불행히도 새로운 사용자를 위해 사용하고 이해하기가 조금 더 어렵습니다. 어떤 돌연변이가 발생하면 새 컬렉션이 생깁니다. 그런 다음 이전 버전을 대체해야합니다. 이것 자체로는 유형 안전하지 않지만,이 모든 것을 처리하는 도구가 있습니다.

var foo = ImmutableList<string>.Empty; 
ImmutableInterlocked.Update(ref foo, list => list.Add("woot")); 

list.Add("woot")foo을 기반으로 새 목록을 반환하고 ImmutableInterlocked.Update는 수집 참조가 제대로 업데이트되었는지 결정할 때까지 foo를 업데이트하려고합니다. 작업을 다시 실행하여 잠금 (list.Add("woot"))으로 바꿉니다.