我正在使用ASP.NET 4.0构建应用程序。
我有一个名为entries的表。参赛作品可以通过Facebook浏览。我想实现通过喜欢排序的能力,所以我采取的方法是存储每个条目的喜欢数量并使用该列进行排序。问题是获得喜欢的数量所涉及的开销。我认为我正在使用的方法现在可以改进,因为只获取13个条目的数据需要4秒,这太长了。
我使用FB图形api和JSON.NET来解析响应。在下面的代码中,我有一个类型为Entry的列表,我使用应用程序设置和条目ID获取条目的类似URL。 这就是我在做的事情:
foreach (Entry entry in entries)
{
int likes;
try
{
// the url that is tied to the entry
string url = "http://graph.facebook.com/?ids=" + Properties.Settings.Default.likeUrl + "?id=" + entry.EntryId;
//open a WebClient and get the results of the url
WebClient client = new WebClient();
Stream data = client.OpenRead(url);
StreamReader reader = new StreamReader(data);
string s = reader.ReadToEnd();
//parse out the response
var json = JObject.Parse(s);
//shares are how many likes the entry has
likes = Convert.ToInt32(json.First.First.SelectToken("shares").ToString());
}
catch (Exception ex)
{
likes = 0;
}
}
正如我所说,这种方法非常昂贵。如果有人可以建议一个更好的方法来做我在这里尝试的东西,我真的很感激帮助。非常感谢!
答案 0 :(得分:2)
的方法,
您没有丢弃您的信息流或信息流阅读器。这可能对个人表现没有帮助,但是你可以看到后来放慢速度......也尝试使用parallel extentions,这需要在处理变量时多加小心。这只是一个例子:
编辑:我忘了webclient也是一次性的。这需要每次处理,否则它会挂在连接上一段时间。这实际上可能会有所帮助。
private object locker;
private int _likes = 0;
private int Likes
{
get
{
lock(locker)
{
return _likes;
}
}
set
{
lock(locker)
{
_likes = value;
}
}
}
void MyMethod()
{
Parallel.ForEach(entries, entry =>
{
using(WebClient client = new WebClient())
using(Stream data = client.OpenRead(url))
using(StreamReader reader = new StreamReader(data))
{
....
}
}
}
答案 1 :(得分:1)
由于发出网络请求的开销,对循环中的每个项目执行单独的API调用会很慢。您是否考虑将查询的所有13个项目的查询批处理到单个API调用中?我不知道它是否适用于您正在运行的查询,但我知道facebook API支持批处理查询的方法。您可以运行批处理,使得一个批处理的输出进入同一批次中的其他查询。您可能必须切换到通过Graph API进行FQL查询。
您也可以考虑将API调用移动到客户端,并使用javascript API实现它们。这会将API工作卸载到用户的浏览器,这将使您的应用程序更好地扩展。如果你不这样做,你至少应该考虑罗伯特关于异步拨打电话的建议。