2011-09-12 6 views
0

C#で私がUsonを使ってJsonデータをダウンロードしたいWPFアプリケーションを開発しています。コードは、ダウンロードしたJsonデータをオブジェクトに逆シリアル化し、その後、オブジェクトには、並行して要求したいJsonデータをさらに要求する必要があるUrisのリストがあります。ダウンロードされたJsonデータには、より多くのUrisがリクエストする可能性があります。コードでは、必要に応じて親と子のWebClientでWebClient.CancelAsyncを実行できる必要があります。私は、タスク並列ライブラリを見て、それを把握して実装するのが難しいと思っています。 TPLのCancellationトークンを使用してCancelAsyncまたはCancelAsyncを呼び出してTPLのCancellationトークンをキャンセルする必要があるかどうかは不明です。子供のWebClientにネストされたタスクを使用する必要があるかどうかはわかりません....TPLを使用したWebClientリクエストのツリー階層

誰もが同様のシナリオがあり、新しいTPLを使用してそれを実装..あなたは、コードのスニペットを共有気になる場合...

感謝。

答えて

1

// The initial Uri 
Uri initialUri = ...; 

// A function to return the JSON string from a given Uri 
Func<Uri, string> getJason = ...; 

// Turn the JSON into the next set of Uris to fetch 
Func<string, IEnumerable<Uri>> getUris = ...; 

次に、Rxを使用して、これらの関数を、タスクプールを使用してオブザーバブルを返す関数に変換します。

Func<Uri, IObservable<string>> getJasonObsFunc = u => 
    Observable 
     .FromAsyncPattern<Uri, string>(
      getJason.BeginInvoke, 
      getJason.EndInvoke) 
     .Invoke(u) 
     .ObserveOn(Scheduler.TaskPool); 

Func<string, IObservable<Uri>> getUrisObsFunc = j => 
    Observable 
     .FromAsyncPattern<string, IEnumerable<Uri>>(
      getUris.BeginInvoke, 
      getUris.EndInvoke) 
     .Invoke(j) 
     .ObserveOn(Scheduler.TaskPool) 
     .SelectMany(xs => xs.ToObservable()); 

コールバックを取得するにはコールバックが必要ですUri/JSONはペアになっています。このような何か:

var subscription = getAllUris(initialUri).Subscribe(); 

Func<Uri, IObservable<Uri>> getAllUris = null; 
getAllUris = u => 
    Observable 
     .Return<Uri>(u) 
     .Merge(
      from j in getJasonObsFunc(u).Do(k => callback(u, k)) 
      from u1 in getUrisObsFunc(j) 
      from u2 in getAllUris(u1) 
      select u2); 

は、その後、あなたが次の行を使用して、この良さのすべてを呼び出す

:ここ

Action<Uri, string> callback = (u, j) => 
    Console.WriteLine(String.Format("{0} => {1}", u, j)); 

は再帰的に各JSON文字列を取得します再帰的なLINQクエリですクエリの実行をキャンセルする場合は、次のように呼び出します:

subscription.Dispose(); 

Rxはすべてのタスクを処理し、すべてのタスクをキャンセルします。

こちらがお役に立てば幸いです。ここで

はRxのためのリンクです:

0

実行中のタスクの数を制御できないため、ネストされたタスクを作成しないようにすることをお勧めします。ブレイキングコレクションを使用したディスパッチパターンを使用できます。必要に応じて作業を追加することができます。また、すべてのオブジェクトがダウンロードされると、待機中のすべてのタスクのブロックを解除するためにCompleteAddingを呼び出します。私は、これはキャンセルタスクなどを必要とせず、非常に簡単に行うことができるTPLの上にReactive Extensions (Rx)を使用して提案することができた場合、私はあなたが持っていると仮定できる場合

関連する問題