BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース 新.NET Async制御フローの説明

新.NET Async制御フローの説明

ブックマーク

原文(投稿日:2011/04/26)へのリンク

Alan Berman氏は最近、新しい.NET Asyncフィーチャの制御フローを詳述している。 Visual Basic Teamサイトで彼が 説明しているのは、Async フィーチャによって、呼び出しコードとレスポンスコードを同じ場所に置けるようになる、ということである。これは、 AsyncAwait キーワードによって可能になる。 Async と印された関数は非同期なタスクを戻し、 Await はタスクが終了するまで 、制御フローを呼び出し関数に戻す。

Async 関数を使うには、2つのタスクオブジェクトが必要である。1つはAsyncと印された関数用のオブジェクト、もう1つは実際に非同期な動きが起きるオブジェクトである。 Await が非同期関数内のタスクで呼ばれると、制御は直ちに呼びたし関数に戻る。実際の非同期コールが終了すると、新しいスレッドはAwaitコールの後の実行を獲得する。 AwaitAsync と印された関数の外のタスクで呼ぶことはできない。次のコードは Visual Basic Teamサイトにある例を拡張したものである。

Module Module1
 Sub Main()
  ShowInfo("In Main before Async call")
  Dim task As Task(Of String) = GetWebPageAsync("http://www.msdn.com/")
  ShowInfo("In Main after Async call", task.Id)
  Dim content As String = task.Result '結果が返るまで待つ(同期的)
  ShowInfo("In Main after Async call has completed", task.Id)
  Console.ReadKey()
 End Sub

 Private Async Function GetWebPageAsync(ByVal webAddress As String) As Task(Of String)
  Dim theTask As Task(Of String) = New WebClient().DownloadStringTaskAsync(New Uri(webAddress))
  ShowInfo("In GetWebPageAsync before Await", theTask.Id)
  Dim result As String = Await theTask '呼び出し関数に戻る
  ShowInfo("In GetWebPageAsync After Await", theTask.Id)
  Return result
 End Function

 Private Sub ShowInfo(ByVal msg As String, Optional taskId As Integer = 0)
  Console.WriteLine("Thread ID: " & System.Threading.Thread.CurrentThread.ManagedThreadId & " " & msg & IIf(taskId = 0, "", " task: " & taskId.ToString))
 End Sub
End Module

サンプル出力:
Thread ID: 8 In Main before Async call
Thread ID: 8 In GetWebPageAsync before Await task: 1
Thread ID: 8 In Main after Async call task: 2
Thread ID: 13 In GetWebPageAsync After Await task: 1
Thread ID: 8 In Main after Async call has completed task: 2

注目すべきは、一度Awaitがよばれると、主スレッドはAsync関数で終了することである。非同期のwebリクエストが終了すると、別のスレッドがAsync関数の残りの処理を実行する。Async関数が終了するまで、結果をリクエストした主スレッドはブロックしている。このフィーチャは、VB.NET と C#の Async CTP の一部である。

この記事に星をつける

おすすめ度
スタイル

BT