C# 网络爬虫的Rx框架

C# 网络爬虫的Rx框架,c#,system.reactive,C#,System.reactive,我发现Rx框架看起来对异步操作非常有用,但我不明白如何使用它下载大量页面 我在写这样的东西 var en = Enumerable.Range(0,100).Select(x => WebRequest.Create("http://google.com")).Select(x => Observable.FromAsyncPattern<WebResponse>(x.BeginGetResponse, x.EndGetResponse)().Subscribe

我发现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();
var en=Enumerable.Range(0100)。选择(x=>WebRequest.Create(“http://google.com选择(x=>Observable.FromAsyncPattern(x.BeginGetResponse,
x、 EndGetResponse().Subscribe(r=>Console.WriteLine(r.ContentLength)).ToList();

当然它不起作用。如何正确操作?

编辑:修改为提供简单的错误处理

以下是您需要做的:

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));
var url=new[]
{
"http://stackoverflow.com/questions/10693617/"
+“rx-framework-for-a-web-crawler”,
"http://stackoverflow.com/",
"http://stackoverflow.com/users/259769/enigmativity",
};
Func创建=
url=>
可观察。延迟(()=>
{
var wr=WebRequest.Create(url);
返回
可观察
.FromAsyncPattern(
wr.BeginGetResponse,
wr.EndGetResponse(响应)
.Invoke()
.Catch(可观察到的返回(null));
});
变量查询=
从URL.ToObservable()中的u开始
从r开始创建(u)
选择新的
{
URL=u,
ContentLength=r==null?-1L:r.ContentLength,
};
ServicePointManager.DefaultConnectionLimit=100;
Subscribe(x=>Console.WriteLine(x));

不过,我更倾向于提供更好的错误处理。我将发送一个包含异常的元组,而不仅仅是一个
null
值。

编辑:修改为提供简单的错误处理

以下是您需要做的:

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));
var url=new[]
{
"http://stackoverflow.com/questions/10693617/"
+“rx-framework-for-a-web-crawler”,
"http://stackoverflow.com/",
"http://stackoverflow.com/users/259769/enigmativity",
};
Func创建=
url=>
可观察。延迟(()=>
{
var wr=WebRequest.Create(url);
返回
可观察
.FromAsyncPattern(
wr.BeginGetResponse,
wr.EndGetResponse(响应)
.Invoke()
.Catch(可观察到的返回(null));
});
变量查询=
从URL.ToObservable()中的u开始
从r开始创建(u)
选择新的
{
URL=u,
ContentLength=r==null?-1L:r.ContentLength,
};
ServicePointManager.DefaultConnectionLimit=100;
Subscribe(x=>Console.WriteLine(x));

不过,我更倾向于提供更好的错误处理。我将发送一个包含异常的元组,而不仅仅是一个
null
值。

您在这里想要实现什么?实际情况如何?Rx可能不是正确的方法-任务并行库可能足够了。@yamen在这个例子中,我只是尝试异步下载100页。我问了一个关于在这个任务中使用TPL的问题,有人向我解释说TPL对CPU限制的操作很好。对于I\O操作,异步方法更好。Rx使得使用异步方法变得简单,对吗?当然,我不需要Rx也能做到,但我想学习一些新的东西。合理的-VS 11或.NET 4.5是一种选择吗?你想在这里实现什么?实际情况如何?Rx可能不是正确的方法-任务并行库可能足够了。@yamen在这个例子中,我只是尝试异步下载100页。我问了一个关于在这个任务中使用TPL的问题,有人向我解释说TPL对CPU限制的操作很好。对于I\O操作,异步方法更好。Rx使得使用异步方法变得简单,对吗?当然,我可以不用Rx,但我想学习一些新的东西。合理-VS11或.NET4.5是一个选项吗?谢谢。但是如果我有一个异常(比如404),订阅就会停止工作。我怎么能假装呢?谢谢。但是如果我有一个异常(比如404),订阅就会停止工作。我怎么能假装呢?