2012-05-21 51 views
0

我發現Rx框架看起來對於異步操作非常有用,但我無法理解如何使用它來下載大量頁面。Web爬蟲的Rx框架

我試圖寫這樣的事情

var en = Enumerable.Range(0,100).Select(x => WebRequest.Create("http://google.com")).Select(x => Observable.FromAsyncPattern<WebResponse>(x.BeginGetResponse, 
    x.EndGetResponse)().Subscribe(r => Console.WriteLine(r.ContentLength))).ToList(); 

Ofcourse它不工作。如何做到這一點?

+0

你想在這裏實現什麼?什麼是實際情況? Rx可能不是正確的方法 - 任務並行庫可能就足夠了。 – yamen

+0

@yamen在這個例子中,我只是試圖異步下載100頁。我詢問了有關使用TPL執行此任務的問題,並且有人向我解釋說,tpl適用於CPU綁定操作。對於I \ O操作,異步方法更好。 Rx使得異步方法很容易,對吧?當然,我可以做到沒有Rx,但我想學習新的東西。 – Neir0

+0

合理 - 是VS 11還是.NET 4.5的選項? – yamen

回答

3

編輯:修改爲提供簡單的錯誤處理。

這裏就是你需要做的:

var urls = new[] 
     { 
      "http://stackoverflow.com/questions/10693617/" 
        + "rx-framework-for-a-web-crawler", 
      "http://stackoverflow.com/", 
      "http://stackoverflow.com/users/259769/enigmativity", 
     }; 

Func<string, IObservable<WebResponse>> create = 
    url => 
     Observable.Defer(() => 
     { 
      var wr = WebRequest.Create(url); 
      return 
       Observable 
        .FromAsyncPattern<WebResponse>(
         wr.BeginGetResponse, 
         wr.EndGetResponse) 
        .Invoke() 
        .Catch(Observable.Return<WebResponse>(null)); 
     }); 

var query = 
    from u in urls.ToObservable() 
    from r in create(u) 
    select new 
    { 
     URL = u, 
     ContentLength = r == null ? -1L : r.ContentLength, 
    }; 

ServicePointManager.DefaultConnectionLimit = 100; 

query.Subscribe(x => Console.WriteLine(x)); 

我會更傾向於雖然提供比這更好的錯誤處理。我會派出一個包含異常的元組,而不僅僅是一個null的值。

+0

謝謝。但是,如果我有一個異常(如404)訂閱剛停止工作。我怎麼假裝它? – Neir0

+0

@ Neir0 - 我添加了一些錯誤處理。 – Enigmativity