2011-09-12 3 views
0

C#에서 Json 데이터를 다운로드하려는 Uri가있는 WPF 앱을 개발 중입니다. 이 코드는 다운로드 된 Json 데이터를 객체에 대해 deserialize 할 것이고, 그 후에 객체는 병렬로 요청하고 싶은 더 많은 Json 데이터를 요청해야하는 Uris 목록을 가지고 있습니다. 다운로드 한 Json 데이터에는 Uris가 요청할 수도 있습니다. 코드는 필요할 때 부모와 자식 WebClient에서 WebClient.CancelAsync를 수행 할 수 있어야합니다. 태스크 병렬 라이브러리를보고 있으며이를 이해하고 구현하기가 어렵습니다. TPL의 Cancellation 토큰을 사용하여 CancelAsync 또는 CancelAsync를 호출하여 TPL의 취소 토큰을 취소해야하는지 확실하지 않습니다. 그리고 자녀 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가 모든 작업을 처리하고 모두 취소합니다.

이 정보가 도움이되기를 바랍니다. 여기

는 수신에 대한 링크입니다 :

0

실행중인 작업의 수를 제어 할 수 없기 때문에 중첩 된 작업을하지 않는 것이 좋습니다. 대신 제한된 수의 작업이있는 BlockingCollection을 사용하여 디스패치 패턴을 사용할 수 있으며 컬렉션에서 작업을 파견합니다 필요한 경우 더 많은 작업을 추가 할 수 있으며 모든 객체가 다운로드되면 CompleteAdding을 호출하여 대기중인 모든 작업의 ​​차단을 해제 할 수 있습니다. 나는 다음이 취소 작업 등을 위해 필요없이 아주 쉽게 할 수있는 TPL 위에 Reactive Extensions (Rx)을 사용하는 것이 좋습니다 수 있다면 나는 당신이 추측 할 수있는 경우