2012-12-12 2 views
5

저는 새로운 asyncawait 키워드를 C#에서 찾고 있습니다.FileStream WriteAsync 및 혼란을 기다리십시오.

나는 MSDN FileStream.WriteAsync()example을보고 있는데, 나는 뭔가를 이해하고 있는지 확신 할 수 없었다. 내가하지 않는 것은 await의 위치입니다

using System; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.IO; 

namespace WpfApplication1 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     private async void Button_Click(object sender, RoutedEventArgs e) 
     { 
      UnicodeEncoding uniencoding = new UnicodeEncoding(); 
      string filename = @"c:\Users\exampleuser\Documents\userinputlog.txt"; 

      byte[] result = uniencoding.GetBytes(UserInput.Text); 

      using (FileStream SourceStream = File.Open(filename, FileMode.OpenOrCreate)) 
      { 
       SourceStream.Seek(0, SeekOrigin.End); 
       await SourceStream.WriteAsync(result, 0, result.Length); 
      } 
     } 
    } 
} 

다음과 같이

예입니다. 항상 WriteAsync()에 의해 반환되는 Task 항목을 사용할 수없는 것으로 보입니다.이 경우 항상 구문 오류가 발생하기 때문입니다. 그래서 이것을 컴파일 할 수있는 유일한 방법은 await을 호출하는 것입니다.

하지만 이렇게하면 통화가 끝날 때까지 기다리지 않습니까? 이것은 비동기 적이 지 않습니다 ...

+0

'작업'항목을 "가져가"는 것은 무엇을 의미합니까? –

+0

@Jon 'Task t = SourceStream.WriteAsync (result, 0, result.Length);'와 같은 것이고 나중에 'await t;'를 수행합니다. – Andrew

+2

당신은 분명히 그렇게 할 수 있습니다. –

답변

13

await의 이해에 문제가 있다고 생각합니다.

그러나 이렇게하면 통화가 끝날 때까지 기다리지 않습니까? 이 ... 아주 비동기하지하게

await 일, 당신이 "비동기 블록"- 비동기 작업이 완료되면 비동기 기능은 계속되지만 즉시 호출이 즉시 완료됩니다.

따라서 Button_Click이 반환되기 때문에 UI 스레드가 차단 해제되지만 파일 쓰기 작업이 완료되면 실행은 UI 스레드에서 여전히 await 표현의 끝으로 돌아갑니다. FileStream을 닫고 비동기 기능을 완료하십시오.

await 표현 (예 : UI 업데이트) 이후에 어떤 일이 벌어 졌는지 분명하게 알 수 있습니다. 하지만 네, 실제로는 비동기입니다. 이 보이는 코드를 쓸 수 있습니다. 동기식입니다.

+0

그래서'await' 다음에 어떤 메소드'doWork()'를 만들었습니다. 메소드는 호출되지 않습니다. 쓰기가 끝날 때까지? – Andrew

+3

@Andrew : 참으로.그러나 비동기 함수가 완료 될 때까지 기다리는 동안 UI 스레드를 유지하지는 않습니다. 그것은 피자를 주문하는 것과 같습니다. 피자가 ​​배달 될 때까지 먹을 수는 없지만 대신 다른 일을 할 수 있습니다. –

+0

나는 그것이 맞는 것 같아요. 감사! – Andrew

1

기다리는 동안 실제로 대기하지 않습니다. 컴파일러는 기다린 후에 모든 코드를 소위 말하는 복잡한 작업을 수행하고 완료 될 때 해당 작업을 실행하도록 지시합니다. WriteAsync 예를 들면, 즉시 완료 될 경우이보다 효율적으로 실행될 수있는 바와 같이이 간략화 물론

FileStream SourceStream = File.Open(filename, FileMode.OpenOrCreate); 
SourceStream.Seek(0, SeekOrigin.End); 
Task t = SourceStream.WriteAsync(result, 0, result.Length); 
t.ContinueWith(_ => SourceStream.Dispose()); 

:

기본적 Button_Click 방법의 마지막 라인으로 변환된다.