C# 网络爬虫的Rx框架
我发现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
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),订阅就会停止工作。我怎么能假装呢?