SP ProcessBatchData dentro do Receptor de Evento, problema de desempenho lento
-
10-12-2019 - |
Pergunta
Eu estou escrevendo um Receptor de Evento em uma Biblioteca de Documentos para criar uma nova lista a partir do upload de arquivo do excel.ele é executado em ItemAdded() e ItemUpdated() do evento.
Antes de chamar um método para adicionar novos Itens à Lista eu preciso limpar Itens antigos, inicialmente, eu tentei isso com a maneira tradicional (iteração em ordem decrescente e excluir todos os registros) e agora com o ProcessBatchData
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 é um pouco melhor, mas ainda não é exato, o problema é que, enquanto debuggin uma vez que o controle alcança a linha var deleteBatch = site.OpenWeb().ProcessBatchData(BuildBatchDeleteCommand(site.OpenWeb().Lists[listName]));
Ele toma o controle de volta para o documento tela de upload e na maioria das vezes não bater o restante do código, no Entanto, se os registros são realmente baixos ( < 100), em seguida, o processo e toma o controle para a linha seguinte ( InsertIntoList(ExcelRecords, site.OpenWeb().Lists[listName].Items);
).
Não é capaz de descobrir se o seu um thread problema, Se eu fizer este trabalho a minha thread para colocar o sono, por algum tempo, até que o ProcessBatch termina seu trabalho e o controle mover para a próxima linha.
A função completa parece
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);
}
}
}
});
}
Geeks por favor, me aponte na direção certa.Eu realmente aprecio a ajuda e tempo.
Paulo
Solução
Provavelmente, este não é a causa raiz de seus problemas de desempenho, mas parte dela.Seu código é escrito de uma forma bastante ineficiente forma, abrir webs para a direita e para a esquerda e olhando para a lista várias vezes.Algo como isto não é a mesma coisa, mas de forma mais eficiente:
Se o seu recurso for web escopo:
var web = properties.Feature.Parent as SPWeb;
se o site escopo
var site = properties.Feature.Parent as SPSite;
if(site == null) return;
var web = site.OpenWeb(properties.WebUrl);
e como MdMazzotti apontou que você realmente precisa descartar a web neste cenário, gostaria de usar a instrução usando, substituir a última linha com este:
using(var web = site.OpenWeb(properties.WebUrl)){
e adicionar um extra }
no fim das seguintes
:
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);
}