2014-12-08 1 views
0

이것은 다중 스레드 프로세스에 대한 필자의 첫 경험이며 어떻게 작동하는지 이해하는 데 어려움이 있습니다.핸들 다중 스레드 프로세스

내 시나리오는 다음과 같습니다.

서버 목록이 약 15 개 있습니다. 그런 다음 각 서버를 vCenter가 속한 목록에 추가합니다. 따라서 약 15 대의 서버와 5 대의 vCenters가 있으면 각 서버를 해당 vCenter로 설정하기 위해 적어도 3 번 serverList를 반복해야합니다. 아래 코드가 실행되면 서버 목록에서 서버가 제거됩니다.

List<Server> serverList = new List<Server>(); 

//populate vCenters using the serverList 

foreach(vCenter v in vCenters) 
{ 
    //Connect to the vCenter and bring back data 
    //remove the server from the serverList 
} 

문제는 각 호출이 완료 될 때까지 이전을 기다리고되지 않고, 첫 번째 서버가 두 번째 서버는 다음 연결하는 첫 번째 서버가 데이터를 다시 제공 한 후 연결하기 때문에 이것 때문에의 SERVERLIST 일관성 머물되지 않는 것입니다. 분명히 여기에 멀티 스레딩이 있습니다. 그러나 모든 vCenter가 데이터를 다시 가져올 때까지 각 vCenter를 연결하고 데이터를 가져오고 나머지는 보류라고 말할 수 있기를 원합니다. 아무도 나에게 이걸하는 방법에 대한 좋은 제안을 줄 수 있습니까? 나는 작업과 스레딩을 살펴 봤지만 기대했던대로하는 것은 아닙니다.

편집 여기

나는 현재를 처리하고 방법

public void getData() 
{ 
    foreach(vCenter vCenter1 in vCenters) 
    { 
     VimClient client = connectToVC(vCenter1); 
     NameValueCollection vmFilter = new NameValueCollection(); 
     vmFilter.Add("name", hostName); 
     VirtualMachine vm = (VirtualMachine)client.FindEntityView(typeof(VirtualMachine), null, vmFilter, null); 
     Console.WriteLine("cpu", getVMSpec(vm, "vCPU")); 
     Console.WriteLine("mem", getVMSpec(vm, "Mem")); 

    } 

} 

public String getVMSpec(VirtualMachine vm, String type) 
    { 
     if(type.Equals("vCPU")) 
      return vm.Summary.Config.NumCpu.ToString(); 
     return vm.Summary.Config.MemorySizeMB.ToString(); 
    } 

Action<object> action = (object obj) => 
{ 
    getData(); 
}; 
System.Threading.Tasks.Task t1 = System.Threading.Tasks.Task.Factory.StartNew(action, "gettingData"); 
t1.Wait(); 

이상적으로 GetData의 각 VCENTER에 다중 스레드 프로세스를 수행하고 응용 프로그램을 계속 하나 개의 스레드에 데이터를 다시 가져올 것이며, getData 메소드가 호출 될 때만 스레드를 분할합니다.

 while (Queue.Count > 0 || isVCentersEmpty() == false) 
     { 
      setVCenters(); // sets the vCenter buckets to any available servers from the Queue 

      Console.WriteLine("Begin getData"); 
      var result = Parallel.ForEach(vCenters, getData);    
      while (!result.IsCompleted) 
      { 
       Console.WriteLine("gettingData..."); 
      } 
      Console.WriteLine("End getData"); 
     } 

EDIT2

이것은 당신의 parrallel 생각 당 나의 새로운 기능은 그러나 "GetData의 시작"날이 함께 실행하는 다른 스레드가 여전히 있다고 생각하게 끝 GetData의 전에 한 번 이상 출력되고있다. 어떤 아이디어? 도와 주셔서 감사합니다!

편집 3

List<Server> Queue = [server1]... [server15] 

List<vCenter> vCenters = [vCenter1] ... [vCenter5] 

15 개 서버와 5 vCenter에 있습니다.

while (Queue.Count > 0 || isVCentersEmpty() == false) 
{ 
    setVCenters(); // sets the vCenter buckets to any available servers from the Queue 

    Console.WriteLine("Begin getData"); 
    var result = Parallel.ForEach(vCenters, rightsize);    
    while (!result.IsCompleted) 
    { 
     Console.WriteLine("Getting Data..."); 
    } 
    Console.WriteLine("End getData"); 
} 
+1

당신은 당신'연결 _how_ 표시해야합니다 :

public void getData(vCenter v) { VimClient client = connectToVC(v); NameValueCollection vmFilter = new NameValueCollection(); vmFilter.Add("name", hostName); VirtualMachine vm = (VirtualMachine)client.FindEntityView(typeof(VirtualMachine), null, vmFilter, null); Console.WriteLine("cpu", getVMSpec(vm, "vCPU")); Console.WriteLine("mem", getVMSpec(vm, "Mem")); } 

그런 다음 TPL 나가서과 같이 각 VCENTER을 처리 할 수 ​​있습니다 vCenter에 연결하여 데이터를 다시 가져옵니다. –

+1

흐름을 보여주는 코드가 추가되었습니다. –

+1

VimClient 클라이언트 = connectToVC (vCenter1) ... VimClient 클라이언트 = connectToVC (v)가 아니어야합니까? 그렇지 않으면 모두 동일한 인스턴스에 연결됩니다. –

답변

1

근본적으로 잘못된 트랙에 있습니다. 당신은 각 vCenter에 대한 스레드를 생성해야하며, 생성 한 스레드는 vCenters 목록을 통해 반복하지 않아야합니다. TPL을 사용하여 시스템의 코어를 사용할 수도 있습니다. 이해가 더 간단 할 수도 있습니다.

PARAM로 VCENTER 받아 들일 수

변화 GetData의 :

var result = Parallel.ForEach(vCenters, getData); 

    while (!result.IsCompleted) 
    { 
     //do some other work; this is your main controlling thread. 
    } 
+0

정적 메서드 여야합니까? –

+0

아니요, 콘솔 앱에 신속하게 입력했습니다. 당신은 정전기를 없앨 수 있습니다. 나는 그것을 편집 할 것이다. –

+0

다른 수정 사항을 작성했는데 확인할 수 있습니까? –