2014-04-01 1 views
2

ping 할 수있는 호스트 이름을 가진 datatable 참조를 전달할 때 각 호스트에 ping을 시도한 다음 해당 열과 행의 값을 변경하려고하는 메소드를 작성하려고합니다. 핑 성공에.Parallel.ForEach 루프에서 참조 된 데이터 테이블을 변경하십시오.

그러나 Parallel.ForEach 메서드에서 참조를 사용할 수 없습니다. 이 일을 할 수있는 방법이 있습니까? - 따라서 액세스가 동기화되어 있어야합니다

public void checkON(ref DataTable PCS) 
    { 

     Parallel.ForEach(PCS.AsEnumerable(), pc => 
      { 
       string loopIp = pc["Name"].ToString(); 
       if (PingIP(loopIp)) 
       { 
        DataRow[] currentpc = PCS.Select("Name = '{0}'", loopIp); 
        currentpc[0]["Online"] = "ON"; 
       } 
       else 
       { 
        DataRow[] currentpc = PCS.Select("Name = '{0}'", loopIp); 
        currentpc[0]["Online"] = "OFF"; 
       } 
      } 
     );} 
+0

그럼 왜'ref'가 필요한가요? 당신의 코드에서 나는 이유를 볼 수 없습니다. 게다가'DataTable'은 쓰레드에 안전합니까? (IMO하지만 ... 우리는 확실합니까?) –

+0

@Adriano 전 꽤 * 확신하지 못합니다 *; p –

답변

3

코드 가 명시 적으로 스레드 안전하다는 것을을 말한다 않는 한, 당신이 그것을 가정해야이 없습니다 :

여기 내 코드입니다. 코드의 ref은 아무 의미가 없습니다. 각 pcDataRow, 그래서 직접 그 액세스 할 수 있습니다 someLockObject가 호출자의 모든간에 공유되는

string loopIp; 
lock(someLockObject) { 
    loopIp = (string)pc["Name"]; 
} 
string online = PingIP(loopIp) ? "ON" : "OFF"; 
lock(someLockObject) { 
    pc["Online"] = online; 
} 

을, 당신은 스레딩 모델에 대한 가정 할 수 없기 때문에 :

object someLockObject = new object(); 
Parallel.ForEach(PCS.AsEnumerable(), pc => 
     { ... }); 

DataTable은 행에 데이터를 저장하지 않으므로 행을 잠글 수 없습니다 (행에 실제로 저장합니다).

+0

그래,이게 맞아. 도와 주셔서 감사합니다. 꽤 오랫동안 여기에 갇혀있어. 초급 : D 조하지만 질문 : 만약 당신이 수도 :) 왜하려고합니다. 데이터 테이블에서 병렬 루프에 해당 행을 찾지 않습니다. 또 다른 질문은 UI 스레드를 잠그지 않고 데이터 테이블에 대한 변경 사항을 실시간으로 볼 수 있도록이 함수를 구현하는 가장 좋은 방법이 될 것입니다. 이 datatable은 DataGridView 컨트롤의 데이터 소스 역할을합니다. – dazgen

+1

@dazgen'DataTable'은 변경 알림을 게시합니다. ** 정말 나쁜 생각 ** 다른 스레드에서 변경하고있는 동안이 스레드를 적극적으로 연결하려면 ...하지만 항상 같은 규칙을 동결하지 않기 위해 UI 스레드를 차단하지 마십시오. 'Parallel.ForEach'는 동기 호출입니다 (모든 호출이 완료 될 때까지 차단됩니다), UI 스레드를 차단하는 것은 정확히 수행중인 작업입니다. –

관련 문제