2010-04-30 3 views
1

FileVersionInfo 문자열을 수집해야하는 공유에 약 1500 개의 파일이 있습니다. 그래서 나는 이런 내 게이트웨이의 static 메소드 생성이 같은 DegreeOfParallelism과 PLINQ 전화에TPL - 정적 메서드와 구조체 메서드 사용

private static string GetVersionInfo(string filepath) 
{ 
    FileVersionInfo verInfo = FileVersionInfo.GetVersionInfo(filepath); 
    return string.Format("{0}.{1}.{2}.{3}", verInfo.ProductMajorPart, verInfo.ProductMinorPart, 
              verInfo.ProductBuildPart, verInfo.ProductPrivatePart).Trim(); 
} 

그리고 사용 FileAndVersion 구조체를, I/O 관련

resultList = dllFilesRows.AsParallel().WithDegreeOfParallelism(20) 
        .Select(r => 
        { 
         var symbolPath = r.Filename; 
         return new FilenameAndVersion{Filename=symbolPath, Version=GetVersionInfo(symbolPath)}; 
        }) 
        .ToArray(); 

나중에 내가 구조체 수정

private struct FilenameAndVersion 
{ 
    private string _version, _filename; 
    public string Version { get { return _version; } } 
    public string Filename { get { return _filename; } } 

    private void SetVersion() 
    { 
     FileVersionInfo verInfo = FileVersionInfo.GetVersionInfo(this.Filename); 
     this._version = string.Format("{0}.{1}.{2}.{3}", verInfo.ProductMajorPart, verInfo.ProductMinorPart, 

                        verInfo.ProductBuildPart, verInfo.ProductPrivatePart).Trim(); 
} 
public FilenameAndVersion(string filename, string version) 
{ 
    this._filename = filename; 
    this._version = string.Empty; 
    SetVersion(); 
} 

}

그리고 그것을 사용 : FileAndVersion로

resultList = dllFilesRows.AsParallel().WithDegreeOfParallelism(20) 
        .Select(r => 
        { 
         var symbolPath = r.Filename; 
         return new FilenameAndVersion(symbolPath, String.Empty); 
        }) 
        .ToArray(); 

질문은 어쨌든 나를 돕기 위해 사용되는 좋은 패턴입니까? 파일이 SAN에 연결된 RAID 10이있는 서버에 있다는 사실을 잊어 버렸습니다. TPL (또는 병렬 어떤 형태)를 사용하여 Sunit

답변

2

모든 파일이 동일한 디스크에있는 경우 병렬로 수행하면 전혀 도움이되지 않습니다. 디스크는 한 번에 한 가지만 읽을 수 있으므로 병렬 처리에 대해 잊어 버리는 것이 좋습니다. 스레딩 오버 헤드를 제거하고 순차적으로 실행되도록하십시오.

만약 당신이 이것을 병렬로 실행한다면 결국 그 곳 곳곳을 샅샅이 뒤지고 더 느린 전체 읽기를 끝내는 디스크가 될 것입니다.

파일이 서로 다른 물리적 드라이브에 있거나 FTP와 같은 네트워크를 통해 연결된 경우 병렬 처리를 좀 더 제어하고 각 물리적 디스크에 대해 단일 작업으로 나누는 것을 고려하십시오.

내 조언은 당신이 뭔가를 평행하게 만들기위한 확고한 의지를하기 전에 그것을 벤치마킹하는 것입니다.

+0

파일이 SAN이 연결된 FileServer에 있습니다. – Sunit

+0

@Sunit : 내가 말한 것은 여전히 ​​사실 일 수 있습니다. 귀하의 네트워크 파이프가 제한되어 있으므로 병렬 vs 순차가 무차별 차별화를하지 못하고 네트워크 속도에 구속을받습니다. 알아야 할 유일한 방법은 벤치마킹/프로파일 링하는 것입니다. 나는 그 시간에 네트워크/샌프란시드에 크게 의존하고있는 것 같아 피크 시간대와 오프 피크 시간대에 테스트를 실행합니다.당신은 단지 GUI 또는 다른 작업을 위해 CPU를 네트워크를 기다리는 최대 무료 동안 대부분 유휴 상태 일 것이다 단지 1 백그라운드 스레드에서이 모든 많이 넣어 더 낫다 사실을 발견했습니다. –

+0

그래, 난 이미 VS2010 도구를 사용하여 프로파일했다. 우리의 경우, 10RAID/1 기가비트 네트워크와 SAN이 동기화 IO 대 TPL을 사용하여 더 나은 결과를 제공하고 취급이 된 것으로 보인다. 그래서 지금 우리는 그 길을 가기로 결정했다. – Sunit

1

파일을 처리 할 때 I/당신이 파일이있는 것을 보장 할 수있는 방법이 없다면 O는 속도 그것까지보다 실행 속도를 느리게하는 것이 실제로 가능성이 높습니다 병렬로 액세스되는 디스크는 서로 다른 물리적 디스크 또는 솔리드 스테이트 디스크에 있습니다. 자기 저장은 랜덤 액세스 I/O (본질적으로 여기서 강요하는)보다 순차적 I/O에서 훨씬 더 나은 경향이 있습니다.

그러나 항상 그렇듯이 변경 사항의 영향을 프로필 링하고 실제로 측정해야합니다.

명확히하려면 : 배경에 고가의 파일 작업을 실행 UI를 막지 않도록하기 위해 할 수있는 좋은 일이 (바람직하게는 불행히도 제공하지 않습니다 FileVersionInfo I/O 완료 포트를 사용하여), 또는 ASP 환경에 따라 .NET 요청. 그러나 이는 병렬에서 실행하는 것과 많이 다릅니다. TPL은 주로 CPU 집약적 인 작업의 병렬 처리를위한 것이며, 여러 CPU 코어가 작업을 더 빠르게 완료하는 데 도움을 줄 수 있습니다.