Visual Basicで非同期通信を行うときはWithEventsを使うとスッキリした形で実装できることは前回お伝えしました。
今回ご紹介するRx (Reactive Extentions) を使うとさらにスッキリします。
なお、Windows PhoneではRxは標準項目ですが、最新版のReactive Extensionsでは一部名前空間が異なりますので、ここからダウンロードして最新版で確認ください。
まずはおさらいとして前回のコードを見てみましょう。
Friend WithEvents Cli As New WebClient
Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles Me.Loaded
Cli.DownloadStringAsync(New Uri("http://blogs.msdn.com/b/shintak/rss.aspx", UriKind.Absolute))
End Sub
Private Sub Clit_DownloadStringCompleted(sender As Object,
e As System.Net.DownloadStringCompletedEventArgs) _
Handles Cli.DownloadStringCompleted
If e.Error IsNot Nothing Then
MessageBox.Show("エラー:" & e.Error.Message)
Else
Dim sr As New StringReader(e.Result)
Dim xr As XmlReader = XmlReader.Create(sr)
Dim sf As SyndicationFeed = SyndicationFeed.Load(xr)
Me.DataContext = sf
End If
End Sub
ではこのコードをRxを使った形に変更してみましょう。
System.Reactiveを参照設定に追加してから次のようにFromEventPatternを設定したからDownLoadStringAsyncで非同期ダウンロードを行います。
System.Reactive.Linq.Observable.FromEventPattern(Of DownloadStringCompletedEventArgs)(cli, "DownLoadStringCompleted") _
.Subscribe(Sub(x)
If x.EventArgs.Error IsNot Nothing Then
MessageBox.Show("エラー:" & x.EventArgs.Error.Message)
Else
Dim sr As New IO.StreamReader(x.EventArgs.Result)
Dim xr As XmlReader = XmlReader.Create(sr)
Dim sf As SyndicationFeed = SyndicationFeed.Load(xr)
Me.DataContext = sf
End If
End Sub)
cli.DownloadStringAsync(New Uri("http://blogs.msdn.com/b/shintak/rss.aspx", UriKind.Absolute))
Rxを使うとイベントプロシージャをイベントポイントが別々にならないため読み方さえわかってしまえばイベントプロシージャがわからず四苦八苦することもなくなるかもしれません。