我正在使用 ASP.NET 4.0构建一个应用程序。
我有一个名为条目的表。参赛作品可以通过Facebook点赞。我想实现通过喜欢排序的功能,所以我正在采用存储每个条目的喜欢数量并使用该列进行排序的方法。问题是获得喜欢数量所涉及的开销。我认为我正在使用的方法可以像现在一样改进,因为仅获取 13 个条目的数据需要 4 秒,这太长了。
我正在使用FB图形api和 JSON.NET 来解析响应。在下面的代码中,我有一个条目类型的列表,我使用与条目 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;
}
}
正如我所说,这种方法非常昂贵。如果有人能提出一种更好的方法来做我在这里尝试的事情,我将不胜感激。多谢!
方法,
您不会处置流或流读取器。 这可能对个人表现没有帮助,但你以后可能会看到速度变慢......还要尝试使用并行扩展,这在处理变量时需要更加小心。 这只是一个例子:
编辑:我忘了网络客户端也是一次性的。 每次都需要处理掉它,否则它会挂在连接上一段时间。 这实际上可能会有所帮助。
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))
{
....
}
}
}
由于发出网络请求的开销,对循环中的每个项目执行单独的 API 调用会很慢。您是否考虑过将所有 13 个项目的类似查询批处理到单个 API 调用中?我不知道它是否适用于您正在运行的查询,但我知道 facebook API 支持批处理查询的方法。您可以运行批处理,以便一个批处理的输出进入同一批处理中的其他查询。可能需要切换到通过图形 API 进行 FQL 查询。
您还可以考虑将 API 调用移动到客户端,并使用 javascript API 实现它们。这会将 API 工作卸载到用户的浏览器,这将使您的应用程序更好地扩展。如果你不这样做,你至少应该考虑罗伯特关于异步调用的建议。