1

我正在使用 ASP.NET 4.0 构建一个应用程序。

我有一个名为条目的表。条目可以通过 Facebook 点赞。我想实现通过喜欢排序的能力,所以我采用存储每个条目的喜欢数量并使用该列进行排序的方法。问题是获得喜欢的数量所涉及的开销。我认为我现在使用的方法可以改进,因为仅获取 13 个条目的数据需要 4 秒,这太长了。

我正在使用 FB graph 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;
        }

    }   

正如我所说,这种方法非常昂贵。如果有人可以提出更好的方法来做我在这里尝试的事情,我将非常感谢您的帮助。非常感谢!

4

2 回答 2

2

方法,

您没有处理您的流或流阅读器。这可能对个人性能没有帮助,但稍后您可能会看到速度变慢......也尝试使用并行扩展,这需要在处理变量时更加小心。这只是一个例子:

已编辑:我忘记了 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))
        {
        ....
        }
    }
}
于 2012-10-03T13:38:40.957 回答
1

由于发出网络请求的开销,对循环中的每个项目执行单独的 API 调用会很慢。您是否考虑过将所有 13 个项目的点赞查询批处理到单个 API 调用中?我不知道它是否适用于您正在运行的查询,但我知道 facebook API 支持批处理查询的方法。您可以运行批处理,以便一个输出进入同一批处理中的其他查询。您可能必须切换到通过 Graph API 进行 FQL 查询。

您还可以考虑将 API 调用移至客户端,并使用 javascript API 实现它们。这会将 API 工作卸载到用户的浏览器,这将使您的应用程序可以更好地扩展。如果您不这样做,您至少应该考虑 Robert 提出的异步调用的建议。

于 2012-10-03T14:45:36.310 回答