我正在开发NopCommerce 2.40,并尝试使用c#生成站点地图,将其提交给Google网站管理员工具。
我的代码
_writer = new XmlTextWriter(stream, Encoding.UTF8);
_writer.Formatting = Formatting.Indented;
_writer.WriteStartDocument();
_writer.WriteStartElement("urlset");
_writer.WriteAttributeString("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9");
_writer.WriteAttributeString("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
_writer.WriteAttributeString("xsi:schemaLocation", "http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd");
GenerateUrlNodes();
_writer.WriteEndElement();
_writer.Close();
在这个GenerateUrlNodes()方法中,调用了不同的方法 e.g
WriteStores();
WriteStoresCategories();
WriteStoresProducts();
第三种写商店产品的方法。
foreach (var store in stores)
{
//TODO add a method for getting URL (use routing because it handles all SEO friendly URLs)
if (store.Id != 1)
{
var products = _productService.SearchProducts(0, 0, null, null, null, 0, null, false, 1, new List<int>(), ProductSortingEnum.Position, 0, int.MaxValue, store.Id, false);
foreach (var product in products)
{
var url = string.Format("{0}s/{1}/{2}/p/{3}/{4}", _webHelper.GetStoreLocation(false), store.Id, store.GetSeName(), product.Id, product.GetSeName());
var updateFrequency = UpdateFrequency.Weekly;
var updateTime = product.UpdatedOnUtc;
WriteUrlLocation(url, updateFrequency, updateTime);
}
}
}
由于每个商店都有5到6k种产品的多个商店,因此花费的时间太长了。因此,当我尝试将此站点地图提交给google时,它会抛出超时错误。有没有办法优化这个或避免循环生成xml
有人可以帮我吗?
答案 0 :(得分:3)
这里要做的第一件事是删除冗余。您似乎每个产品调用_webHelper.GetStoreLocation(false)
一次,每个产品调用store.GetSeName()
两次 - 但两者都不取决于产品。所以作为一个直接的事情:
var location = _webHelper.GetStoreLocation(false);
foreach (var store in stores)
{
var seName = store.GetSeName();
//TODO add a method for getting URL (use routing because it handles all SEO friendly URLs)
if (store.Id != 1)
{
var products = _productService.SearchProducts(0, 0, null, null, null, 0, null, false, 1, new List<int>(), ProductSortingEnum.Position, 0, int.MaxValue, store.Id, false);
foreach (var product in products)
{
var url = string.Format("{0}s/{1}/{2}/p/{3}/{4}", location, store.Id, seName, product.Id, seName);
var updateFrequency = UpdateFrequency.Weekly;
var updateTime = product.UpdatedOnUtc;
WriteUrlLocation(url, updateFrequency, updateTime);
}
}
}
SearchProducts
显然是每个商店,因为它涉及store.Id
,因此我们无法推广;然而,看起来stores
循环可以简单地并行化;例如,如果这是进行http调用,那么在这里调查Parallel.ForEach
是值得的,但问题就变成了排序和并发;您可能需要使用Parallel
创建每个结果(作为字符串或类似字符串),然后当所有字符串都可用时,循环显示它们进行实际写入 - 从而保留原始顺序。