2012-05-26 3 views
0

저는 Reactive Extension 초보자입니다. Gideon Engelberth는 내 질문에 Reactive Extension에 대한 훌륭한 답을주었습니다.IObservable 할당 방법 <Unit> XDocument 인스턴스에 대한 반환 값

How to convert img url to BASE64 string in HTML on one method chain by using LINQ or Rx

지금 나는하여 XDocument 인스턴스에 IObservable 반환 값을 할당하는 방법이 두 번째 질문이 있습니다.

기드온이 저에게 벨로우즈 샘플을주었습니다.

public IObservable<Unit> ReplaceImageLinks(XDocument document) 
    { 
     return (from element in GetImages(document) 
       let address = new Uri(element.Attribute("src").Value) 
       select (from data in DownloadAsync(address) 
         select Convert.ToBase64String(data) 
         ).Do(base64 => element.Attribute("src").Value = base64) 
       ).Merge() 
       .IgnoreElements() 
       .Select(s => Unit.Default); 
    } 

저는 이렇게하고 싶습니다. 버드 힘들 것 같습니다 ...

public void Convert(XDocument input, out XDocument output) 
{ 
    output = ReplaceImageLinks(input); 
} 

답변

0

그래서 여기에있는 것이 유용합니다. 기디언이 당신의 질문에 대답 한 것 같지만 아마도 당신의 추가 요구 사항을 아는 것이 아닙니다. 그래서 당신은 XDoc을 가지고, 경로의 Image src 속성을 모두 경로가 나타내는 BASE64 conent로 변환하려고한다고 가정합니다. 그런 다음 모든 처리가 완료되면 새 XDoc 객체를 반환하려고합니다. 옳은?

그런 경우라면 일 수 있습니다.

public IObservable<XDocument> ReplaceImageLinks(XDocument document) 
{ 
    return Observable.Create<XDocument>(o=> 
    { 
     try{ 
      var images = document.Descendants("Image"); 
      Parallel.ForEach(images, SwapUriForContent); 
      o.OnNext(document); 
      o.OnCompleted(); 
     } 
     catch(Exception ex) 
     { 
      o.OnError(ex); 
     } 
     return Disposable.Empty; //Should really be a handle to Parallel.ForEach cancellation token. 
    }); 
} 

private static void SwapUriForContent(XElement imageElement) 
{ 
    var address = new Uri(imageElement.Attribute("src").Value, UriKind.RelativeOrAbsolute); 
    imageElement.Attribute("src").Value = Download(address); 
} 

public static string Download(Uri input) 
{ 
    //TODO Replace with real implemenation 
    return input.ToString().ToUpper(); 
} 

난 그냥 그러나

string str = 
    @"<?xml version=""1.0""?> 
    <!-- comment at the root level --> 
    <Root> 
     <Child>Content</Child> 
     <Image src=""image.jpg""/> 
     <Child> 
      <Image src=""image2.jpg""/> 
     </Child> 
    </Root>"; 
XDocument doc = XDocument.Parse(str); 
ReplaceImageLinks2(doc).Dump(); 

테스트 어떤이 잘못된 일이 있습니다. 첫째, 우리는 국가를 돌연변이시키고 있습니다. 동시성을 처리 할 때 이것은 좋은 시작이 아닙니다. 올바른 값을 가진 새 XDoc을 반환해야합니다. 두 번째는 Rx보다 TPL 문제가 더 많이 보인다. Rx는 들어오는 데이터의 스트리밍을 처리하는 데 가장 적합합니다. 여기서는 병렬 처리를 수행해야합니다. 나는 훨씬 더 나은 선택은 단지 일이라고 생각한다.

public Task<XDocument> ReplaceImageLinks3(XDocument source) 
{ 
    return Task.Factory.StartNew(()=> 
    { 
     var copy = new XDocument(source); 
     var images = copy.Descendants("Image"); 
     Parallel.ForEach(images, SwapUriForContent); 
     return copy; 
    }); 
} 

IntroToRx.com

에 내 책 When to Use Rx의 섹션을 참조