我正在文档库上编写事件接收器,以从上传的 Excel 文件创建新列表。它在 ItemAdded() 和 ItemUpdated() 事件上运行。

在调用将新项目添加到列表的方法之前,我需要清除旧项目,我最初使用传统方式尝试此操作(按降序迭代并删除所有记录),现在使用 处理批量数据

 using (SPSite site = new SPSite(properties.WebUrl))
                        {
                            if (site.OpenWeb().Lists[listName].Items.Count > 0)
                            {
                                var deleteBatch = site.OpenWeb().ProcessBatchData(BuildBatchDeleteCommand(site.OpenWeb().Lists[listName]));
                            }
                            InsertIntoList(ExcelRecords, site.OpenWeb().Lists[listName].Items);
                        }

ProcessBatachData 更好一些,但仍然不准确,问题是在调试时,一旦控件到达该行 var deleteBatch = site.OpenWeb().ProcessBatchData(BuildBatchDeleteCommand(site.OpenWeb().Lists[listName]));

它将控制权带回文档上传屏幕,大多数时候不会触及剩余的代码,但是如果记录确实很少(< 100),那么它会进行处理并将控制权带到下一行( InsertIntoList(ExcelRecords, site.OpenWeb().Lists[listName].Items); ).

无法确定这是否是线程问题,如果我让这项工作工作,我会让线程休眠一段时间,直到 ProcessBatch 完成其工作并控制移动到下一行。

完整的功能看起来像

 public override void ItemUpdated(SPItemEventProperties properties)
        {
            UpdateMarketingCalendar(properties);
            base.ItemUpdated(properties);
        }


private void UpdateMarketingCalendar(SPItemEventProperties properties)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate
            {
                try
                {
                    using (SPSite site = new SPSite(properties.WebUrl))
                    {
                        SPList list = site.OpenWeb().Lists[listName];

                        bool recordsRetrieved;
                        DataTable ExcelRecords = GetRecordsFromExcel(properties.ListItem, out recordsRetrieved);

                        if (recordsRetrieved)
                        {
                            if (list.ItemCount > 0)
                            {
                                var deleteBatch = site.OpenWeb().ProcessBatchData(BuildBatchDeleteCommand(list));
                            }
                            InsertIntoList(ExcelRecords, list.Items);
                        }
                    }
                }

            });
        }

极客请指出我正确的方向。我真的很感谢你的帮助和时间。

维沙尔

有帮助吗?

解决方案

这可能不是性能问题的根本原因,但只是其中的一部分。您的代码以相当低效的方式编写,向左和向右打开网页并多次查找列表。像这样的东西做同样的事情但更有效:

如果您的功能是网络范围的:

    var web = properties.Feature.Parent as SPWeb;

如果站点范围

    var site = properties.Feature.Parent as SPSite;
    if(site == null) return;
    var web = site.OpenWeb(properties.WebUrl);

正如 MdMazzotti 指出的那样,在这种情况下您实际上需要处理网络,我将使用 using 语句,将最后一行替换为:

using(var web = site.OpenWeb(properties.WebUrl)){

并添加一个额外的 } 在以下结束时:

    if(web == null || !web.Exists) return;

    var list = web.Lists[listName]
    if (list != null && list.Items.Count > 0)
    {
        var deleteBatch = web.ProcessBatchData(BuildBatchDeleteCommand(list));
    }

    InsertIntoList(ExcelRecords, list.Items);
}
许可以下: CC-BY-SA归因
scroll top