C# Sharepoint 2010-更新大型列表,过程非常缓慢且超时
我的情况是,我必须根据记录是否有打开或关闭的项目,将源记录列表状态列更新为打开或关闭-项目列表可以有许多项目通过项目中的源记录ID和客户ID链接到源记录,代码是检索客户机项目,然后检查是否有结束日期,如果没有-它的打开-如果有-它的关闭。这些sharepoint列表很大 我已经编写了代码,基本上允许我指定一个开始ID,然后当我单击运行按钮时,它将在停止之前处理如此多的记录-我将其放在适当的位置,因为这个过程非常缓慢,甚至超时,但我不明白为什么它如此缓慢和良好。。不稳定-如果我尝试处理超过150条记录-它会超时,服务器本身是一个具有24gb ram的八核系统,因此我认为它不是服务器,可能是我的代码C# Sharepoint 2010-更新大型列表,过程非常缓慢且超时,c#,sharepoint,sharepoint-2010,C#,Sharepoint,Sharepoint 2010,我的情况是,我必须根据记录是否有打开或关闭的项目,将源记录列表状态列更新为打开或关闭-项目列表可以有许多项目通过项目中的源记录ID和客户ID链接到源记录,代码是检索客户机项目,然后检查是否有结束日期,如果没有-它的打开-如果有-它的关闭。这些sharepoint列表很大 我已经编写了代码,基本上允许我指定一个开始ID,然后当我单击运行按钮时,它将在停止之前处理如此多的记录-我将其放在适当的位置,因为这个过程非常缓慢,甚至超时,但我不明白为什么它如此缓慢和良好。。不稳定-如果我尝试处理超过150条
protected void Button1_Click(object sender, EventArgs e)
{
SPWeb web = SPControl.GetContextWeb(this.Context);
string SPsiteUrl = SPContext.Current.Web.Url;
Label1.Text = "Running";
int start;
start = Convert.ToInt32(TextBox1.Text);
start = int.Parse(TextBox1.Text);
int end = start + 150;
int count = 0;
using (SPSite oSite = new SPSite(SPsiteUrl))
{
using (SPWeb oWeb = oSite.OpenWeb("/Client"))
{
// get lists
SPList oList = oWeb.Lists["Source Records"];
SPList pList = oWeb.Lists["Project"];
// query Source Records
string sQuery = @"<Where><And><Geq><FieldRef Name='ID' /><Value Type='Number'>" + start + "</Value></Geq><Leq><FieldRef Name='ID'/><Value Type='Number'> "+ end +"</Value></Leq></And></Where>";
string sViewFields = @"<FieldRef Name='ID' />";
string sViewAttrs = @"Scope=""Recursive""";
uint iRowLimit = 0;
var oQuery = new SPQuery();
oQuery.Query = sQuery;
oQuery.ViewFields = sViewFields;
oQuery.ViewAttributes = sViewAttrs;
oQuery.RowLimit = iRowLimit;
SPListItemCollection collListItems = oList.GetItems(oQuery);
// for each item
foreach (SPListItem oListItem in collListItems)
{
// get the client id
int id = oListItem.ID;
count = count + 1;
//Label1.Text = "Checking record" + id;
bool isopen = false;
// for each client id access the projects list
// query the closed date
string Query = @"<Where><Eq><FieldRef Name=""Client_x003a_ID"" /><Value Type=""Text"">" + id + "</Value></Eq></Where>";
string pViewFields = @"<FieldRef Name=""End_x0020_Date"" />";
string pViewAttrs = @"Scope=""Recursive""";
uint pRowLimit = 0;
var pQuery = new SPQuery();
pQuery.Query = Query;
pQuery.ViewFields = pViewFields;
pQuery.ViewAttributes = pViewAttrs;
pQuery.RowLimit = pRowLimit;
SPListItemCollection ListItems = pList.GetItems(pQuery);
foreach (SPListItem ListItem in ListItems)
{
try
{
DateTime enddate = (DateTime)ListItem["End_x0020_Date"];
if (enddate != null)
{
isopen = false;
}
// else if the date is null set the open to true
else
{
isopen = true;
}
}
catch
{
string enddate = null;
if (enddate == null)
{
// if the end date is present set project closed to true
isopen = true;
}
}
// if project is open
if (isopen)
{
oWeb.AllowUnsafeUpdates = true;
SPListItem itemupdate = oWeb.Lists["Source Records"].Items.GetItemById(id);
itemupdate["Status"] = "Open";
itemupdate.Update();
oWeb.AllowUnsafeUpdates = false;
// set records on source record to open
}
//else // project is closed
//{
// oWeb.AllowUnsafeUpdates = true;
// SPListItem itemupdate = oWeb.Lists["Source Records"].Items.GetItemById(id);
// itemupdate["Status"] = "Closed";
// itemupdate.Update();
// oWeb.AllowUnsafeUpdates = false;
// // set the record to closed
//}
}
}
Label1.Text = "Finished Number of records checked: " + count + " of " + collListItems.Count;
}
}
}'
您需要更新嵌套循环的代码。与此相反:
foreach (SPListItem item1 in sPList.GetItems(sPQuery1))
尝试使用以下方法:
SPListItemCollection items1 = sPList.GetItems(sPQuery1);
foreach (SPListItem item1 in items1)
详情请参阅此页
更新:您必须尝试摆脱嵌套循环。我认为您可以通过在项目列表的源列表中添加一个引用,并引用那里的结束日期列来实现这一点。而不是
SPListItem itemupdate = oWeb.Lists["Source Records"].Items.GetItemById(id);
试试这个:
SPListItem itemupdate = oWeb.Lists["Source Records"].GetItemById(id);
代码是从wsp中提取的编码文件-已编辑以包含整个代码,包括注释掉的代码。他的问题是,他在循环中执行复杂而昂贵的查询,这就是他的主要成本所在。这一改变不会有多大影响。对不起,我强烈反对。项目是一项非常昂贵的操作。本质上,它将从列表中检索所有项目。这是一个循环。所以如果源记录列表中有1000-2000个项,那么要考虑collListItems中的每个SPListItem oListItem将需要很多时间。总的来说,这段代码有几个严重的问题,而不仅仅是一个。例如,SPWeb.Lists[]也是一个非常昂贵的操作,您应该从循环etcb中移出,但它只是有条件地发生。这是一个问题,但它并没有改变这个算法的核心设计有缺陷的事实。他根本不应该在双嵌套循环中按ID获取项目,此外,他甚至不应该有一个双嵌套循环,其中每个循环表示一个DB查询。因此,虽然这确实解决了一些问题,但当你完成时,仍然会留下一个不完整的解决方案。你所建议的改变不会改变任何事情。foreach循环只对IEnumerable对象求值一次,而不是在循环的每次迭代中。这与你链接到的博客文章完全不同。