The answer is not to make the user interface wait at all, but to "go with the (asynchronous) stream."
, # 5 , CLR, Silverlight WP7.
Microsoft.Phone.Reactive, WP7 Reactive Extensions (Rx) SDK. , , , .
, - , :
- - IObservable 1
Do, "" (, )Select "" , ( )ForkJoin , .
1 IObservable , . , WebClient, , Observable DownloadStringAsync ( , ):
public static class ObservableWebClient
{
public static IObservable<string> DownloadStringObservable(
this WebClient webClient, Uri uri)
{
return Observable.Create(observer =>
{
var disposable = new CompositeDisposable();
var completedObservable = Observable.FromEvent<
DownloadStringCompletedEventHandler,
DownloadStringCompletedEventArgs
>(
h => new DownloadStringCompletedEventHandler(h),
h => webClient.DownloadStringCompleted += h,
h => webClient.DownloadStringCompleted h= h
);
disposable.Add(completedObservable
.SelectMany(ev =>
{
return (ev.EventArgs.Error != null)
? Observable.Throw<string>(ev.EventArgs.Error)
: Observable.Return(ev.EventArgs.Result);
})
.Subscribe(observer));
disposable.Add(Disposable.Create(
() => webClient.CancelAsync()));
return disposable;
});
}
}
:
, Do + "normalizing", (String). , ( ForkJoin, )
var webClientA = new WebClient();
var webClientB = new WebClient();
var webClientC = new WebClient();
Observable.ForkJoin(
webClientA.DownloadStringObservable(uriA),
webClientB.DownloadStringObservable(uriB),
webClientC.DownloadStringObservable(uriC),
)
.ObserveOnDispatcher()
.Subscribe(dataArray =>
{
this.DataA = dataArray[0];
this.DataB = dataArray[1];
this.DataC = dataArray[2];
});