2016-10-20 4 views
0

비교합니까, 뭔가에 있었다 foreach 루프를 사용하여 현재 코드에서 mainList에 32 개의리스트가 있습니다.스레딩 및 목록, 어떻게 각각의 통과와 내가 다른 목록에 비교하는 중첩 된 목록을 끌어하기 위해 스레드를 사용하기 위해 노력하고있어

foreach(var item in mainList) 
{ 
    if(item.key == "unRead") 
    { 
     foreach(var subItem in item.value) // evt do a List<string> temp = item.value first 
     { 
      foreach(var compItem in compareList) 
      { 
       if(compItem == subItem) resList.Add(compItem); 
      } 
     } 
     item.remove(); // I actualy wanted to change from unRead to read, but I figured I could just remove it from the list. 
    } 
} 

이것은 내가 스레드를 사용하고 10 무언가의 최대 스레드 양 EVT seperat 스레드에서 각 목록을 통해 갈 경우 패스트을 할 수 있어야합니다. 그래서 제가 시도한 것은 이것을하고있었습니다.

foreach(var item in mainList) 
{ 
    Thread myThread = new Thread(() => 
    { 
     if(item.key == "unRead") 
     { 
      foreach(var subItem in item.value) // evt do a List<string> temp = item.value first 
      { 
       foreach(var compItem in compareList) 
       { 
        if(compItem == subItem) resList.Add(compItem); 
       } 
      } 
      item.remove(); // I actualy wanted to change from unRead to read, but I figured I could just remove it from the list. 
     } 
    }); 
    myThread.start(); 
} 

그러나 이것은 전혀 예상 출력을 제공 dident ...

그래서 내가 잘못 뭐하는 거지?

+0

예상 결과가 어떻게 보이는지, 현재 결과는 무엇인지 구체적으로 적어주십시오. – nozzleman

+0

아니면 그냥 속도를 올리는 것입니까? – nozzleman

+0

'resList'는 다중 스레드에서 수정되기 때문에 잠겨 야합니다. –

답변

2

resList은 여러 스레드에서 수정되기 때문에 잠겨 야합니다. 또한 모든 스레드가 완료 될 때까지 기다려야합니다. 이를 위해서는 Parallel.Foreach()을 사용해야합니다. 예를 들어

:

Parallel.Foreach(mainList, (item) => 
{ 
    if(item.key == "unRead") 
    { 
     foreach(var subItem in item.value) // evt do a List<string> temp = item.value first 
     { 
      foreach(var compItem in compareList) 
      { 
       if(compItem == subItem) 
        lock(resList) 
         resList.Add(compItem); 
      } 
     } 
    } 
}); 

mainList.RemoveAll(item => item.key == "unRead"); 

이 일부 LINQ - 마법 단락 할 수 있습니다

var resList = mainList.Where(item => item.key == "unRead") 
         .SelectMany(subitem => compareList.Contains(subitem))).ToList(); 
:

및 스레딩/잠금없이

Parallel.Foreach(mainList, (item) => 
{ 
    if(item.key == "unRead") 
    { 
     foreach(var subItem in item.value) // evt do a List<string> temp = item.value first 
     { 
      if(compareList.Contains(subItem)) 
       lock(resList) 
        resList.Add(compItem); 
     } 
    } 
}); 

그것은 Jerone 반 랑겐가 지적한 바와 같이 compareList

+0

이 로직과 공통점을 찾을 수 있습니다. List duplicates = list1.Intersect (list2) .ToList(); –

0

에 대한 HashSet<> 대신 List<> (A)의를 사용하는 것이 유용 할 것, 이미 문제가 목록에 접근이 경쟁 조건을 일으키는 것입니다. 잠금을 도입하여이를 해결하거나 스레드로부터 안전한 컬렉션 구현을 사용할 수 있습니다. 후자의 접근 방식에는 잠금이 필요없는 클래스가 포함되어있어 더 나은 성능 결과를 얻을 수 있습니다. 예를 들어, System.Collections.Concurrent.ConcurrentBag을 살펴보십시오.

어느 쪽이든, 첫 번째 최적화는 최소한이 목록에 10 개 이상의 요소가 포함될 것으로 예상되는 경우 확실히 해시 집합을 비교 목록으로 사용하는 것입니다. 그렇지 않으면 목록이 빨라질 수 있습니다.