我有一个包含~500项的SPListItemCollection。我循环使用for for each循环,每次抓取文件并将其写入pdf文档。我收到错误“线程被中止”。它看起来是一个超时问题,但我不知道如何解决它? 200-300项的收藏品很好。有什么方法可以阻止这个错误。如果我无法增加超时,我将需要批量处理。
更新
我尝试将100个项目分批处理。每个新的100项使用新的spweb和站点并从sharepoint中提取项目。这都是在同一个方法中完成的(所以我没有重新创建我的自定义对象)但是仍然出现相同的错误......
答案 0 :(得分:3)
在记事本等基本文本编辑器中,打开web.config文件,例如“%SYSTEMDRIVE%\Inetpub\wwwroot
-要么-
%SYSTEMDRIVE%\\Inetpub\wwwroot\wss\VirtualDirectories\80 folder
按CTRL + F打开“查找”对话框。
找到以下标记:
<httpRuntime maxRequestLength="51200" />
将其替换为此标记:
<httpRuntime executionTimeout="6000" maxRequestLength="51200" />
这似乎让它对我有用。
答案 1 :(得分:1)
请记住,迭代列表项有一种正确和非常错误的方法,它会对性能产生巨大影响。错误的方法会导致对数据库进行n + 1次调用以获取列表数据;正确的方式只能对数据库进行一次调用。
最差:
for (int i = 0; i < myList.Items.Count; i++)
{
SPListItem thisItem = myList.Items[i];
// yada yada yada
}
为:
foreach (SPListItem item in myList.Items)
{
// yada yada yada
}
右:
SPListItemCollection myItems = myList.Items;
foreach (SPListItem item in myItems)
{
// yada yada yada
}
已更新:要反映更准确的指导
答案 2 :(得分:0)
迭代SPListItemCollection绝不是一个好主意(但遗憾的是有时候唯一的方法)。您可以考虑在LongRunningOperation中包装此代码。这是我自己改编的一些代码:
实际课程:
using System;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.SharePoint;
namespace Common.LongRunningJobs
{
/// <summary>
/// Provides a long running job wrapper around converting multiple files
/// </summary>
[CLSCompliant(false)]
public class FileToPdfLongRunningJob : LongRunningOperationJob
{
private List<string> fileUrls;
/// <summary>
/// Initializes a new instance of the <see cref="FileToPdfLongRunningJob"/> class.
/// </summary>
/// <param name="urls">The urls of the files to create pdfs from.</param>
public FileToPdfLongRunningJob(List<string> urls)
{
fileUrls = urls;
}
/// <summary>
/// Does the actual work of converting the files, while providing the user with status updates.
/// </summary>
public override void DoWork()
{
try
{
using (var currentWeb = Site.OpenWeb(parentWeb))
{
OperationsPerformed = 0;
foreach (var url in fileUrls)
{
SPFile file = currentWeb.GetFile(url);
// DO PDF OUTPUT
StatusDescription = string.Format(CultureInfo.InvariantCulture, "busy converting {0} van {1}, file: {2}...", (OperationsPerformed + 1), TotalOperationsToBePerformed, file.Name);
UpdateStatus();
OperationsPerformed++;
}
}
}
catch (Exception ex)
{
// LOG ERROR
}
}
}
}
使用上述类别:
private void ConvertFiles()
{
const string PROGRESS_PAGE_URL = "/_layouts/LongRunningOperationProgress.aspx";
var urls = new List<string>();
foreach (SPListItem item in yourlistitemcollection)
{
urls.Add(item.File.Url);
}
var longRunningJob = new FileMoveLongRunningJob(urls)
{
Title = "Pdf conversion Long Running Job",
TotalOperationsToBePerformed = urls.Count,
RedirectWhenFinished = true,
NavigateWhenDoneUrl = urlToRedirectTo;//i.e. SPContext.GetContext(Context).List.RootFolder.ServerRelativeUrl
};
longRunningJob.Start(SPContext.Current.Web);
string url = string.Format("{0}{1}?JobId={2}", SPContext.Current.Web.Url, PROGRESS_PAGE_URL, longRunningJob.JobId);
SPUtility.Redirect(url, SPRedirectFlags.Default, Context);
}
答案 3 :(得分:0)
尝试在获取项目之前创建新的SPSite和SPWeb对象(并从新的Web获取它们)。
通常可以解决问题。
答案 4 :(得分:0)
迭代列表的代码中可能存在潜在的陷阱。如果您可以在此处粘贴代码,那将是一件好事。 此外,最好使用Caml查询列表项,并仅选择操作所需的字段而不是全部。