2013-02-11 2 views
9

저는 C#의 새로운 async 기능으로 시작했습니다. 텍스트 파일을 읽고/처리하는 방법에 대해서는 아직 많이 읽지 않았습니다.C# 5.0 async를 사용하여 파일 읽기

나는 로그 파일을 필터링하는 데 사용하는 오래된 스크립트가 있었고 업그레이드 할 생각이었습니다. 그러나 새로운 async/await 구문을 사용하는 것이 맞는지 확실하지 않습니다.

내 머리 속에는 파일을 한 줄씩 읽고 다른 스레드에서 처리하기 위해 전달되는 것을 볼 수 있으므로 결과를 기다리지 않고 계속 진행할 수 있습니다.

제대로 생각하고 있습니까? 아니면 이것을 구현하는 가장 좋은 방법은 무엇입니까?

static async Task<string[]> FilterLogFile(string fileLocation) 
{ 
    string line; 

    List<string> matches = new List<string>(); 

    using(TextReader file = File.OpenText(fileLocation)) 
    {   
     while((line = await file.ReadLineAsync()) != null) 
     { 
      CheckForMatch(line, matches); 
     } 
    } 

    return matches.ToArray(); 
} 

전체 스크립트 : 내 머리에서 http://share.linqpad.net/29kgbe.linq

+0

[msdn docs] (http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx)를 한 번 보았는데, 분명히 잘못된 키워드를 생각하고 있습니다. 방법. 이 경우 실적을 향상시키기 위해 할 수있는 일이 많지 않다고 생각합니다. –

+1

좋습니다. http://blog.jerrynixon.com/2012/06/windows-8-how-to-read-files-in-winrt.html –

답변

9

나는이 라인으로 파일 라인을 읽고 그 결과를 기다리지 않고 계속할 수 있도록 다른 스레드에서 처리를 위해 그것을 통과를 참조하십시오.

하지만 코드가하는 것은 아닙니다. 대신 모든 읽기가 완료되면 배열을 반환합니다 (비동기식으로). 실제로 비동기 적으로 일치 항목을 하나씩 반환하려는 경우 비동기 컬렉션이 필요합니다. 이를 위해 TPL Dataflow의 블록을 사용할 수 있습니다. 예를 들어 :

ISourceBlock<string> FilterLogFile(string fileLocation) 
{ 
    var block = new BufferBlock<string>(); 

    Task.Run(async() => 
    { 
     string line; 

     using(TextReader file = File.OpenText(fileLocation)) 
     {   
      while((line = await file.ReadLineAsync()) != null) 
      { 
       var match = GetMatch(line); 

       if (match != null) 
        block.Post(match); 
      } 
     } 

     block.Complete(); 
    }); 

    return block; 
} 

(당신은 아마 반환 된 블록을 오류있는함으로써, 오류 처리를 추가해야합니다.)

그런 다음 결과를 처리 할 다른 블록에 반환 된 블록을 연결합니다. 또는 블록에서 직접 읽을 수도 있습니다 (ReceiveAsync() 사용).


전체 코드를 살펴보면이 접근법이 도움이 될지 모르겠다. 결과를 처리하는 방식 (각 그룹의 수에 따라 그룹화 한 후 순서를 매기는 방식) 때문에 모든 것을 가질 때까지는 많은 작업을 수행 할 수 없습니다.

+0

더 의미가 있습니다. 예제 tpl 데이터 흐름 코드를 보내 주셔서 감사합니다. 일치 목록이나'CheckForMatch' 메소드를 기다려야할까요? 그것이 내가 동기로 실행하는 것과별로 다르지 않다고 상상한다. –

+1

@Sam'await'은 의미가있는 곳에 만 사용해야합니다. 대부분 IO를 사용하는 코드에 있습니다. 다음은 동기 코드와의 차이점입니다 : 1.'await file.ReadFileAsync()'는 쓰레드를 차단하지 않으므로보다 효율적입니다. 2. 다른 스레드를 차단하지 않고 결과를 읽을 때 처리 할 수 ​​있습니다. – svick